mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1444745 - Part 1: Clear out xptinfo and typelib to make way for the this patch, r=mccr8
Unfortunately, I wasn't able to figure out a way to make firefox build & run in the intermediate stages of these commits. Because of this, I am going to just delete most of the code which I am deleting in the first patch, as I figure that those are somewhat uninteresting changes, and then make the other changes in the following patches. In total, the following things are deleted: 1. All of xpcom/typelib, except for `xpt/tools` - this directory is being subsumed entirely into xpcom/reflect/xptinfo. 2. Most of the code in xpcom/reflect/xptinfo, it is being rewritten to avoid allocating and contain all of the necessary data structures. 3. idl-parser's typelib.py XPT generator, as it will be replaced. 4. Most includes of files which have been deleted. NOTE: xpcom/typelib/xpt/tools/xpt.py was not removed, as it is used by bundling code & bundling tests, which we don't want to remove yet.
This commit is contained in:
parent
0405ef5fa2
commit
f5f86c989e
@ -155,6 +155,10 @@ configure:: $(configure-preqs)
|
||||
ifneq (,$(MAKEFILE))
|
||||
$(OBJDIR)/Makefile: $(OBJDIR)/config.status
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$(OBJDIR)/config.status: $(CONFIG_STATUS_DEPS)
|
||||
else
|
||||
$(OBJDIR)/Makefile: $(CONFIG_STATUS_DEPS)
|
||||
|
@ -28,15 +28,12 @@
|
||||
#include "nsXBLPrototypeBinding.h"
|
||||
#include "nsXBLContentSink.h"
|
||||
#include "xptinfo.h"
|
||||
#include "nsIInterfaceInfoManager.h"
|
||||
#include "nsIDocumentObserver.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsXBLProtoImpl.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsTextFragment.h"
|
||||
#include "nsTextNode.h"
|
||||
#include "nsIInterfaceInfo.h"
|
||||
#include "nsIScriptError.h"
|
||||
|
||||
#include "nsXBLResourceLoader.h"
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "mozilla/URLPreloader.h"
|
||||
#include "mozilla/XPTInterfaceInfoManager.h"
|
||||
#include "mozilla/dom/DOMException.h"
|
||||
#include "mozilla/dom/DOMExceptionBinding.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
@ -32,7 +31,6 @@
|
||||
#include "mozilla/Scheduler.h"
|
||||
#include "nsZipArchive.h"
|
||||
#include "nsWindowMemoryReporter.h"
|
||||
#include "ShimInterfaceInfo.h"
|
||||
#include "nsIException.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
@ -115,8 +113,6 @@ public:
|
||||
|
||||
private:
|
||||
virtual ~nsXPCComponents_Interfaces();
|
||||
|
||||
nsCOMArray<nsIInterfaceInfo> mInterfaces;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -311,8 +307,6 @@ public:
|
||||
|
||||
private:
|
||||
virtual ~nsXPCComponents_InterfacesByID();
|
||||
|
||||
nsCOMArray<nsIInterfaceInfo> mInterfaces;
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "js/Wrapper.h"
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/XPTInterfaceInfoManager.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsPointerHashKeys.h"
|
||||
|
@ -58,7 +58,6 @@ LOCAL_INCLUDES += [
|
||||
'/dom/svg',
|
||||
'/layout/base',
|
||||
'/layout/style',
|
||||
'/xpcom/reflect/xptinfo',
|
||||
]
|
||||
|
||||
if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
|
||||
|
@ -30,7 +30,6 @@
|
||||
|
||||
#include "nsDOMMutationObserver.h"
|
||||
#include "nsICycleCollectorListener.h"
|
||||
#include "mozilla/XPTInterfaceInfoManager.h"
|
||||
#include "nsIObjectInputStream.h"
|
||||
#include "nsIObjectOutputStream.h"
|
||||
#include "nsScriptSecurityManager.h"
|
||||
|
@ -108,7 +108,6 @@
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsIXPConnect.h"
|
||||
#include "nsIInterfaceInfo.h"
|
||||
#include "nsIXPCScriptable.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
@ -101,8 +101,6 @@
|
||||
present.places = true;
|
||||
} else if (aPath.search(/^explicit\/images/) >= 0) {
|
||||
present.images = true;
|
||||
} else if (aPath.search(/^explicit\/xpti-working-set$/) >= 0) {
|
||||
present.xptiWorkingSet = true;
|
||||
} else if (aPath.search(/^explicit\/atoms\/dynamic\/atom-objects$/) >= 0) {
|
||||
present.dynamicAtomObjects = true;
|
||||
} else if (/\[System Principal\].*this-is-a-sandbox-name/.test(aPath)) {
|
||||
@ -260,7 +258,6 @@
|
||||
ok(present.windowObjectsJsCompartments, "window-objects/.../js compartments are present");
|
||||
ok(present.places, "places is present");
|
||||
ok(present.images, "images is present");
|
||||
ok(present.xptiWorkingSet, "xpti-working-set is present");
|
||||
ok(present.dynamicAtomObjects, "dynamic/atom-objects is present");
|
||||
ok(present.sandboxLocation, "sandbox locations are present");
|
||||
ok(present.bigString, "large string is present");
|
||||
|
@ -54,9 +54,6 @@
|
||||
#include "nsThreadPool.h"
|
||||
|
||||
#include "xptinfo.h"
|
||||
#include "nsIInterfaceInfoManager.h"
|
||||
#include "xptiprivate.h"
|
||||
#include "mozilla/XPTInterfaceInfoManager.h"
|
||||
|
||||
#include "nsTimerImpl.h"
|
||||
#include "TimerThread.h"
|
||||
|
@ -55,7 +55,6 @@
|
||||
COMPONENT(MULTIPLEXINPUTSTREAM, nsMultiplexInputStreamConstructor)
|
||||
|
||||
COMPONENT(VARIANT, nsVariantCCConstructor)
|
||||
COMPONENT(INTERFACEINFOMANAGER_SERVICE, nsXPTIInterfaceInfoManagerGetSingleton)
|
||||
|
||||
COMPONENT(HASH_PROPERTY_BAG, nsHashPropertyBagCCConstructor)
|
||||
|
||||
|
@ -91,7 +91,6 @@ LOCAL_INCLUDES += [
|
||||
'../ds',
|
||||
'../glue',
|
||||
'../io',
|
||||
'../reflect/xptinfo',
|
||||
'../threads',
|
||||
'/chrome',
|
||||
'/docshell/base',
|
||||
|
@ -46,7 +46,6 @@ LOCAL_INCLUDES += [
|
||||
'../base',
|
||||
'../build',
|
||||
'../ds',
|
||||
'../reflect/xptinfo',
|
||||
'/chrome',
|
||||
'/modules/libjar',
|
||||
]
|
||||
|
@ -1,307 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# typelib.py - Generate XPCOM typelib files from IDL.
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
"""Generate an XPIDL typelib for the IDL files specified on the command line"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import xpidl
|
||||
import xpt
|
||||
|
||||
# A map of xpidl.py types to xpt.py types
|
||||
TypeMap = {
|
||||
# nsresult is not strictly an xpidl.py type, but it's useful here
|
||||
'nsresult': xpt.Type.Tags.uint32,
|
||||
# builtins
|
||||
'boolean': xpt.Type.Tags.boolean,
|
||||
'void': xpt.Type.Tags.void,
|
||||
'int16_t': xpt.Type.Tags.int16,
|
||||
'int32_t': xpt.Type.Tags.int32,
|
||||
'int64_t': xpt.Type.Tags.int64,
|
||||
'uint8_t': xpt.Type.Tags.uint8,
|
||||
'uint16_t': xpt.Type.Tags.uint16,
|
||||
'uint32_t': xpt.Type.Tags.uint32,
|
||||
'uint64_t': xpt.Type.Tags.uint64,
|
||||
'octet': xpt.Type.Tags.uint8,
|
||||
'short': xpt.Type.Tags.int16,
|
||||
'long': xpt.Type.Tags.int32,
|
||||
'long long': xpt.Type.Tags.int64,
|
||||
'unsigned short': xpt.Type.Tags.uint16,
|
||||
'unsigned long': xpt.Type.Tags.uint32,
|
||||
'unsigned long long': xpt.Type.Tags.uint64,
|
||||
'float': xpt.Type.Tags.float,
|
||||
'double': xpt.Type.Tags.double,
|
||||
'char': xpt.Type.Tags.char,
|
||||
'string': xpt.Type.Tags.char_ptr,
|
||||
'wchar': xpt.Type.Tags.wchar_t,
|
||||
'wstring': xpt.Type.Tags.wchar_t_ptr,
|
||||
# special types
|
||||
'nsid': xpt.Type.Tags.nsIID,
|
||||
'domstring': xpt.Type.Tags.DOMString,
|
||||
'astring': xpt.Type.Tags.AString,
|
||||
'utf8string': xpt.Type.Tags.UTF8String,
|
||||
'cstring': xpt.Type.Tags.CString,
|
||||
'jsval': xpt.Type.Tags.jsval
|
||||
}
|
||||
|
||||
|
||||
# XXXkhuey dipper types should go away (bug 677784)
|
||||
def isDipperType(type):
|
||||
return type == xpt.Type.Tags.DOMString or type == xpt.Type.Tags.AString or type == xpt.Type.Tags.CString or type == xpt.Type.Tags.UTF8String
|
||||
|
||||
|
||||
def build_interface(iface, ifaces):
|
||||
def get_type(type, calltype, iid_is=None, size_is=None):
|
||||
""" Return the appropriate xpt.Type object for this param """
|
||||
|
||||
while isinstance(type, xpidl.Typedef):
|
||||
type = type.realtype
|
||||
|
||||
if isinstance(type, xpidl.Builtin):
|
||||
if type.name == 'string' and size_is is not None:
|
||||
return xpt.StringWithSizeType(size_is, size_is)
|
||||
elif type.name == 'wstring' and size_is is not None:
|
||||
return xpt.WideStringWithSizeType(size_is, size_is)
|
||||
else:
|
||||
tag = TypeMap[type.name]
|
||||
isPtr = (tag == xpt.Type.Tags.char_ptr or tag == xpt.Type.Tags.wchar_t_ptr)
|
||||
return xpt.SimpleType(tag,
|
||||
pointer=isPtr,
|
||||
reference=False)
|
||||
|
||||
if isinstance(type, xpidl.Array):
|
||||
# NB: For an Array<T> we pass down the iid_is to get the type of T.
|
||||
# This allows Arrays of InterfaceIs types to work.
|
||||
return xpt.ArrayType(get_type(type.type, calltype, iid_is), size_is,
|
||||
#XXXkhuey length_is duplicates size_is (bug 677788),
|
||||
size_is)
|
||||
|
||||
if isinstance(type, xpidl.Interface) or isinstance(type, xpidl.Forward):
|
||||
xptiface = None
|
||||
for i in ifaces:
|
||||
if i.name == type.name:
|
||||
xptiface = i
|
||||
|
||||
if not xptiface:
|
||||
xptiface = xpt.Interface(name=type.name)
|
||||
ifaces.append(xptiface)
|
||||
|
||||
return xpt.InterfaceType(xptiface)
|
||||
|
||||
if isinstance(type, xpidl.Native):
|
||||
if type.specialtype:
|
||||
# XXXkhuey jsval is marked differently in the typelib and in the headers :-(
|
||||
isPtr = (type.isPtr(calltype) or type.isRef(calltype)) and not type.specialtype == 'jsval'
|
||||
isRef = type.isRef(calltype) and not type.specialtype == 'jsval'
|
||||
return xpt.SimpleType(TypeMap[type.specialtype],
|
||||
pointer=isPtr,
|
||||
reference=isRef)
|
||||
elif iid_is is not None:
|
||||
return xpt.InterfaceIsType(iid_is)
|
||||
else:
|
||||
# void ptr
|
||||
return xpt.SimpleType(TypeMap['void'],
|
||||
pointer=True,
|
||||
reference=False)
|
||||
|
||||
raise Exception("Unknown type!")
|
||||
|
||||
def get_nsresult():
|
||||
return xpt.SimpleType(TypeMap['nsresult'])
|
||||
|
||||
def build_nsresult_param():
|
||||
return xpt.Param(get_nsresult())
|
||||
|
||||
def get_result_type(m):
|
||||
if not m.notxpcom:
|
||||
return get_nsresult()
|
||||
|
||||
return get_type(m.realtype, '')
|
||||
|
||||
def build_result_param(m):
|
||||
return xpt.Param(get_result_type(m))
|
||||
|
||||
def build_retval_param(m):
|
||||
type = get_type(m.realtype, 'out')
|
||||
if isDipperType(type.tag):
|
||||
# NB: The retval bit needs to be set here, contrary to what the
|
||||
# xpt spec says.
|
||||
return xpt.Param(type, in_=True, retval=True, dipper=True)
|
||||
return xpt.Param(type, in_=False, out=True, retval=True)
|
||||
|
||||
def build_attr_param(a, getter=False, setter=False):
|
||||
if not (getter or setter):
|
||||
raise Exception("Attribute param must be for a getter or a setter!")
|
||||
|
||||
type = get_type(a.realtype, getter and 'out' or 'in')
|
||||
if setter:
|
||||
return xpt.Param(type)
|
||||
else:
|
||||
if isDipperType(type.tag):
|
||||
# NB: The retval bit needs to be set here, contrary to what the
|
||||
# xpt spec says.
|
||||
return xpt.Param(type, in_=True, retval=True, dipper=True)
|
||||
return xpt.Param(type, in_=False, out=True, retval=True)
|
||||
|
||||
if iface.namemap is None:
|
||||
raise Exception("Interface was not resolved.")
|
||||
|
||||
consts = []
|
||||
methods = []
|
||||
|
||||
def build_const(c):
|
||||
consts.append(xpt.Constant(c.name, get_type(c.basetype, ''), c.getValue()))
|
||||
|
||||
def build_method(m):
|
||||
params = []
|
||||
|
||||
def build_param(p):
|
||||
def findattr(p, attr):
|
||||
if hasattr(p, attr) and getattr(p, attr):
|
||||
for i, param in enumerate(m.params):
|
||||
if param.name == getattr(p, attr):
|
||||
return i
|
||||
return None
|
||||
|
||||
iid_is = findattr(p, 'iid_is')
|
||||
size_is = findattr(p, 'size_is')
|
||||
|
||||
in_ = p.paramtype.count("in")
|
||||
out = p.paramtype.count("out")
|
||||
dipper = False
|
||||
type = get_type(p.realtype, p.paramtype, iid_is=iid_is, size_is=size_is)
|
||||
if out and isDipperType(type.tag):
|
||||
out = False
|
||||
dipper = True
|
||||
|
||||
return xpt.Param(type, in_, out, p.retval, p.shared, dipper, p.optional)
|
||||
|
||||
for p in m.params:
|
||||
params.append(build_param(p))
|
||||
|
||||
if not m.notxpcom and m.realtype.name != 'void':
|
||||
params.append(build_retval_param(m))
|
||||
|
||||
methods.append(xpt.Method(m.name, build_result_param(m), params,
|
||||
getter=False, setter=False, notxpcom=m.notxpcom,
|
||||
constructor=False, hidden=m.noscript,
|
||||
optargc=m.optional_argc,
|
||||
implicit_jscontext=m.implicit_jscontext))
|
||||
|
||||
def build_attr(a):
|
||||
# Write the getter
|
||||
methods.append(xpt.Method(a.name, build_nsresult_param(),
|
||||
[build_attr_param(a, getter=True)],
|
||||
getter=True, setter=False,
|
||||
constructor=False, hidden=a.noscript,
|
||||
optargc=False,
|
||||
implicit_jscontext=a.implicit_jscontext))
|
||||
|
||||
# And maybe the setter
|
||||
if not a.readonly:
|
||||
methods.append(xpt.Method(a.name, build_nsresult_param(),
|
||||
[build_attr_param(a, setter=True)],
|
||||
getter=False, setter=True,
|
||||
constructor=False, hidden=a.noscript,
|
||||
optargc=False,
|
||||
implicit_jscontext=a.implicit_jscontext))
|
||||
|
||||
for member in iface.members:
|
||||
if isinstance(member, xpidl.ConstMember):
|
||||
build_const(member)
|
||||
elif isinstance(member, xpidl.Attribute):
|
||||
build_attr(member)
|
||||
elif isinstance(member, xpidl.Method):
|
||||
build_method(member)
|
||||
elif isinstance(member, xpidl.CDATA):
|
||||
pass
|
||||
else:
|
||||
raise Exception("Unexpected interface member: %s" % member)
|
||||
|
||||
parent = None
|
||||
if iface.base:
|
||||
for i in ifaces:
|
||||
if i.name == iface.base:
|
||||
parent = i
|
||||
if not parent:
|
||||
parent = xpt.Interface(name=iface.base)
|
||||
ifaces.append(parent)
|
||||
|
||||
return xpt.Interface(iface.name, iface.attributes.uuid, methods=methods,
|
||||
constants=consts, resolved=True, parent=parent,
|
||||
scriptable=iface.attributes.scriptable,
|
||||
function=iface.attributes.function,
|
||||
builtinclass=iface.attributes.builtinclass,
|
||||
main_process_scriptable_only=iface.attributes.main_process_scriptable_only)
|
||||
|
||||
|
||||
def write_typelib(idl, fd, filename):
|
||||
""" Generate the typelib. """
|
||||
|
||||
# We only care about interfaces that are scriptable.
|
||||
ifaces = []
|
||||
for p in idl.productions:
|
||||
if p.kind == 'interface' and p.attributes.scriptable:
|
||||
ifaces.append(build_interface(p, ifaces))
|
||||
|
||||
typelib = xpt.Typelib(interfaces=ifaces)
|
||||
typelib.writefd(fd)
|
||||
|
||||
if __name__ == '__main__':
|
||||
from optparse import OptionParser
|
||||
o = OptionParser()
|
||||
o.add_option('-I', action='append', dest='incdirs', default=['.'],
|
||||
help="Directory to search for imported files")
|
||||
o.add_option('--cachedir', dest='cachedir', default=None,
|
||||
help="Directory in which to cache lex/parse tables.")
|
||||
o.add_option('-o', dest='outfile', default=None,
|
||||
help="Output file")
|
||||
o.add_option('-d', dest='depfile', default=None,
|
||||
help="Generate a make dependency file")
|
||||
o.add_option('--regen', action='store_true', dest='regen', default=False,
|
||||
help="Regenerate IDL Parser cache")
|
||||
options, args = o.parse_args()
|
||||
file = args[0] if args else None
|
||||
|
||||
if options.cachedir is not None:
|
||||
if not os.path.isdir(options.cachedir):
|
||||
os.mkdir(options.cachedir)
|
||||
sys.path.append(options.cachedir)
|
||||
|
||||
if options.regen:
|
||||
if options.cachedir is None:
|
||||
print >>sys.stderr, "--regen requires --cachedir"
|
||||
sys.exit(1)
|
||||
|
||||
p = xpidl.IDLParser(outputdir=options.cachedir, regen=True)
|
||||
sys.exit(0)
|
||||
|
||||
if options.depfile is not None and options.outfile is None:
|
||||
print >>sys.stderr, "-d requires -o"
|
||||
sys.exit(1)
|
||||
|
||||
if options.outfile is not None:
|
||||
outfd = open(options.outfile, 'wb')
|
||||
closeoutfd = True
|
||||
else:
|
||||
raise "typelib generation requires an output file"
|
||||
|
||||
p = xpidl.IDLParser(outputdir=options.cachedir)
|
||||
idl = p.parse(open(file).read(), filename=file)
|
||||
idl.resolve(options.incdirs, p)
|
||||
write_typelib(idl, outfd, file)
|
||||
|
||||
if closeoutfd:
|
||||
outfd.close()
|
||||
|
||||
if options.depfile is not None:
|
||||
depfd = open(options.depfile, 'w')
|
||||
deps = [dep.replace('\\', '/') for dep in idl.deps]
|
||||
|
||||
print >>depfd, "%s: %s" % (options.outfile, " ".join(deps))
|
||||
for dep in deps:
|
||||
print >>depfd, "%s:" % dep
|
@ -36,7 +36,6 @@ TEST_DIRS += [
|
||||
|
||||
# Can't build internal xptcall tests that use symbols which are not exported.
|
||||
#TEST_DIRS += [
|
||||
# 'reflect/xptinfo/tests',
|
||||
# 'reflect/xptcall/tests,
|
||||
#]
|
||||
|
||||
|
@ -330,5 +330,4 @@ FINAL_LIBRARY = 'xul'
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'../..',
|
||||
'/xpcom/reflect/xptinfo',
|
||||
]
|
||||
|
@ -4,7 +4,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
#ifndef __AARCH64EL__
|
||||
#error "Only little endian compatibility was tested"
|
||||
|
@ -6,7 +6,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
/* Prototype specifies unmangled function name and disables unused warning */
|
||||
static nsresult
|
||||
|
@ -6,7 +6,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
#if !defined(__arm__) && !(defined(LINUX) || defined(ANDROID) || defined(XP_DARWIN))
|
||||
#error "This code is for Linux/iOS ARM only. Please check if it works for you, too.\nDepends strongly on gcc behaviour."
|
||||
|
@ -6,7 +6,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
/* This tells gcc3.4+ not to optimize away symbols.
|
||||
|
@ -6,7 +6,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
#include "xptc_gcc_x86_unix.h"
|
||||
|
||||
extern "C" {
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -6,7 +6,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
/* Prototype specifies unmangled function name and disables unused warning */
|
||||
static nsresult
|
||||
|
@ -6,7 +6,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
extern "C" {
|
||||
nsresult ATTRIBUTE_USED
|
||||
|
@ -7,7 +7,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
static nsresult ATTRIBUTE_USED
|
||||
PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
|
||||
|
@ -7,7 +7,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
static nsresult ATTRIBUTE_USED
|
||||
PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
|
||||
|
@ -6,7 +6,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
#if (_MIPS_SIM != _ABIN32) && (_MIPS_SIM != _ABI64)
|
||||
#error "This code is for MIPS n32/n64 only"
|
||||
|
@ -8,7 +8,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
#if _HPUX
|
||||
#error "This code is for HP-PA RISC 32 bit mode only"
|
||||
|
@ -6,7 +6,6 @@
|
||||
// Implement shared vtbl methods.
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
// The Linux/PPC64 ABI passes the first 8 integral
|
||||
// parameters and the first 13 floating point parameters in registers
|
||||
|
@ -6,7 +6,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
#if defined(AIX)
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
#if defined(AIX)
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
// Implement shared vtbl methods.
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
// The Linux/PPC ABI (aka PPC/SYSV ABI) passes the first 8 integral
|
||||
// parameters and the first 8 floating point parameters in registers
|
||||
|
@ -6,7 +6,6 @@
|
||||
// Implement shared vtbl methods.
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
// The Linux/PPC ABI (aka PPC/SYSV ABI) passes the first 8 integral
|
||||
// parameters and the first 8 floating point parameters in registers
|
||||
|
@ -4,7 +4,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
/* Under the Mac OS X PowerPC ABI, the first 8 integer and 13 floating point
|
||||
* parameters are delivered in registers and are not on the stack, although
|
||||
|
@ -7,7 +7,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
#if defined(sparc) || defined(__sparc__)
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
#if defined(sparc) || defined(__sparc__)
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
#if defined(sparc) || defined(__sparc__)
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
// Keep this in sync with the linux version.
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
// The Darwin/x86-64 ABI passes the first 6 integer parameters and the
|
||||
// first 8 floating point parameters in registers (rdi, rsi, rdx, rcx,
|
||||
|
@ -9,7 +9,6 @@
|
||||
// Keep this in sync with the darwin version.
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
// The Linux/x86-64 ABI passes the first 6 integer parameters and the
|
||||
// first 8 floating point parameters in registers (rdi, rsi, rdx, rcx,
|
||||
|
@ -9,7 +9,6 @@
|
||||
// Keep this in sync with the darwin version.
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
// The Linux/x86-64 ABI passes the first 6 integer parameters and the
|
||||
// first 8 floating point parameters in registers (rdi, rsi, rdx, rcx,
|
||||
|
@ -7,7 +7,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
nsresult ATTRIBUTE_USED
|
||||
PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
|
||||
|
@ -40,5 +40,4 @@ FINAL_LIBRARY = 'xul'
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'../..',
|
||||
'/xpcom/reflect/xptinfo',
|
||||
]
|
||||
|
@ -6,7 +6,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
#ifndef WIN32
|
||||
#error "This code is for Win32 only"
|
||||
|
@ -6,7 +6,6 @@
|
||||
/* Implement shared vtbl methods. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
/*
|
||||
* This is for Windows XP 64-Bit Edition / Server 2003 for AMD64 or later.
|
||||
|
@ -5,7 +5,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
|
||||
/*
|
||||
* This is for Windows 64 bit (x86_64) using GCC syntax
|
||||
|
@ -17,8 +17,4 @@ EXPORTS += [
|
||||
'xptcstubsdef.inc',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/xpcom/reflect/xptinfo',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
@ -6,8 +6,6 @@
|
||||
/* entry point wrappers. */
|
||||
|
||||
#include "xptcprivate.h"
|
||||
#include "xptiprivate.h"
|
||||
#include "mozilla/XPTInterfaceInfoManager.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsISupports.h"
|
||||
#include "xpt_struct.h"
|
||||
#include "xptinfo.h"
|
||||
#include "js/Value.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
|
@ -12,8 +12,6 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
class xptiInterfaceEntry;
|
||||
|
||||
#if !defined(__ia64) || (!defined(__hpux) && !defined(__linux__) && !defined(__FreeBSD__))
|
||||
#define STUB_ENTRY(n) NS_IMETHOD Stub##n() = 0;
|
||||
#else
|
||||
|
@ -1,360 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: set ts=8 sw=4 et tw=78:
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ShimInterfaceInfo.h"
|
||||
|
||||
#include "nsIDOMDOMRequest.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMDocumentFragment.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIDOMGeoPositionError.h"
|
||||
#include "nsIDOMHTMLInputElement.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIDOMOfflineResourceList.h"
|
||||
#include "nsIDOMParser.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsIListBoxObject.h"
|
||||
#include "nsIMessageManager.h"
|
||||
#include "nsISelection.h"
|
||||
#include "nsITreeBoxObject.h"
|
||||
|
||||
#include "mozilla/dom/CSSPrimitiveValueBinding.h"
|
||||
#include "mozilla/dom/CSSStyleDeclarationBinding.h"
|
||||
#include "mozilla/dom/CSSStyleSheetBinding.h"
|
||||
#include "mozilla/dom/CSSValueBinding.h"
|
||||
#include "mozilla/dom/CSSValueListBinding.h"
|
||||
#include "mozilla/dom/DOMParserBinding.h"
|
||||
#include "mozilla/dom/DOMRequestBinding.h"
|
||||
#include "mozilla/dom/DocumentBinding.h"
|
||||
#include "mozilla/dom/DocumentFragmentBinding.h"
|
||||
#include "mozilla/dom/ElementBinding.h"
|
||||
#include "mozilla/dom/EventBinding.h"
|
||||
#include "mozilla/dom/EventTargetBinding.h"
|
||||
#include "mozilla/dom/HTMLAnchorElementBinding.h"
|
||||
#include "mozilla/dom/HTMLAreaElementBinding.h"
|
||||
#include "mozilla/dom/HTMLButtonElementBinding.h"
|
||||
#include "mozilla/dom/HTMLFrameSetElementBinding.h"
|
||||
#include "mozilla/dom/HTMLHtmlElementBinding.h"
|
||||
#include "mozilla/dom/HTMLInputElementBinding.h"
|
||||
#include "mozilla/dom/ListBoxObjectBinding.h"
|
||||
#include "mozilla/dom/MediaListBinding.h"
|
||||
#include "mozilla/dom/MessageEventBinding.h"
|
||||
#include "mozilla/dom/MessageManagerBinding.h"
|
||||
#include "mozilla/dom/NodeListBinding.h"
|
||||
#include "mozilla/dom/NodeBinding.h"
|
||||
#include "mozilla/dom/EventBinding.h"
|
||||
#include "mozilla/dom/OfflineResourceListBinding.h"
|
||||
#include "mozilla/dom/PositionErrorBinding.h"
|
||||
#include "mozilla/dom/RangeBinding.h"
|
||||
#include "mozilla/dom/SelectionBinding.h"
|
||||
#include "mozilla/dom/StorageEventBinding.h"
|
||||
#include "mozilla/dom/StyleSheetBinding.h"
|
||||
#include "mozilla/dom/StyleSheetListBinding.h"
|
||||
#include "mozilla/dom/SVGElementBinding.h"
|
||||
#include "mozilla/dom/TimeEventBinding.h"
|
||||
#include "mozilla/dom/TreeBoxObjectBinding.h"
|
||||
#include "mozilla/dom/XULDocumentBinding.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
struct ComponentsInterfaceShimEntry {
|
||||
constexpr
|
||||
ComponentsInterfaceShimEntry(const char* aName, const nsIID& aIID,
|
||||
const dom::NativePropertyHooks* aNativePropHooks)
|
||||
: geckoName(aName), iid(aIID), nativePropHooks(aNativePropHooks) {}
|
||||
|
||||
const char *geckoName;
|
||||
const nsIID& iid;
|
||||
const dom::NativePropertyHooks* nativePropHooks;
|
||||
};
|
||||
|
||||
#define DEFINE_SHIM_WITH_CUSTOM_INTERFACE(geckoName, domName) \
|
||||
{ #geckoName, NS_GET_IID(geckoName), \
|
||||
mozilla::dom::domName ## Binding::sNativePropertyHooks }
|
||||
#define DEFINE_SHIM(name) \
|
||||
DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIDOM ## name, name)
|
||||
|
||||
/**
|
||||
* These shim entries allow us to make old XPIDL interfaces implementing DOM
|
||||
* APIs as non-scriptable in order to save some runtime memory on Firefox OS,
|
||||
* without breaking the entries under Components.interfaces which might both
|
||||
* be used by our code and add-ons. Specifically, the shim entries provide
|
||||
* the following:
|
||||
*
|
||||
* * Components.interfaces.nsIFoo entries. These entries basically work
|
||||
* almost exactly as the usual ones that you would get through the
|
||||
* XPIDL machinery. Specifically, they have the right name, they reflect
|
||||
* the right IID, and they will work properly when passed to QueryInterface.
|
||||
*
|
||||
* * Components.interfaces.nsIFoo.CONSTANT values. These entries will have
|
||||
* the right name and the right value for most integer types. Note that
|
||||
* support for non-numerical constants is untested and will probably not
|
||||
* work out of the box.
|
||||
*
|
||||
* FAQ:
|
||||
* * When should I add an entry to the list here?
|
||||
* Only if you're making an XPIDL interfaces which has a corresponding
|
||||
* WebIDL interface non-scriptable.
|
||||
* * When should I remove an entry from this list?
|
||||
* If you are completely removing an XPIDL interface from the code base. If
|
||||
* you forget to do so, the compiler will remind you.
|
||||
* * How should I add an entry to the list here?
|
||||
* First, make sure that the XPIDL interface in question is non-scriptable
|
||||
* and also has a corresponding WebIDL interface. Then, add two include
|
||||
* entries above, one for the XPIDL interface and one for the WebIDL
|
||||
* interface, and add a shim entry below. If the name of the XPIDL
|
||||
* interface only has an "nsIDOM" prefix prepended to the WebIDL name, you
|
||||
* can use the DEFINE_SHIM macro and pass in the name of the WebIDL
|
||||
* interface. Otherwise, use DEFINE_SHIM_WITH_CUSTOM_INTERFACE.
|
||||
*/
|
||||
|
||||
const ComponentsInterfaceShimEntry kComponentsInterfaceShimMap[] =
|
||||
{
|
||||
DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIContentFrameMessageManager, ContentFrameMessageManager),
|
||||
DEFINE_SHIM(DOMRequest),
|
||||
DEFINE_SHIM(Document),
|
||||
DEFINE_SHIM(DocumentFragment),
|
||||
DEFINE_SHIM(Element),
|
||||
DEFINE_SHIM(Event),
|
||||
DEFINE_SHIM(EventTarget),
|
||||
DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIDOMGeoPositionError, PositionError),
|
||||
DEFINE_SHIM(HTMLInputElement),
|
||||
DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIListBoxObject, ListBoxObject),
|
||||
DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIMessageSender, MessageSender),
|
||||
DEFINE_SHIM(NodeList),
|
||||
DEFINE_SHIM(Node),
|
||||
DEFINE_SHIM(OfflineResourceList),
|
||||
DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIDOMParser, DOMParser),
|
||||
DEFINE_SHIM(Range),
|
||||
DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsITreeBoxObject, TreeBoxObject),
|
||||
DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsISelection, Selection),
|
||||
};
|
||||
|
||||
#undef DEFINE_SHIM
|
||||
#undef DEFINE_SHIM_WITH_CUSTOM_INTERFACE
|
||||
|
||||
NS_IMPL_ISUPPORTS(ShimInterfaceInfo, nsISupports, nsIInterfaceInfo)
|
||||
|
||||
already_AddRefed<ShimInterfaceInfo>
|
||||
ShimInterfaceInfo::MaybeConstruct(const char* aName, JSContext* cx)
|
||||
{
|
||||
RefPtr<ShimInterfaceInfo> info;
|
||||
for (uint32_t i = 0; i < ArrayLength(kComponentsInterfaceShimMap); ++i) {
|
||||
if (!strcmp(aName, kComponentsInterfaceShimMap[i].geckoName)) {
|
||||
const ComponentsInterfaceShimEntry& shimEntry =
|
||||
kComponentsInterfaceShimMap[i];
|
||||
info = new ShimInterfaceInfo(shimEntry.iid,
|
||||
shimEntry.geckoName,
|
||||
shimEntry.nativePropHooks);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return info.forget();
|
||||
}
|
||||
|
||||
ShimInterfaceInfo::ShimInterfaceInfo(const nsIID& aIID,
|
||||
const char* aName,
|
||||
const mozilla::dom::NativePropertyHooks* aNativePropHooks)
|
||||
: mIID(aIID)
|
||||
, mName(aName)
|
||||
, mNativePropHooks(aNativePropHooks)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::GetName(char** aName)
|
||||
{
|
||||
*aName = ToNewCString(mName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::IsScriptable(bool* aRetVal)
|
||||
{
|
||||
// This class should pretend that the interface is scriptable because
|
||||
// that's what nsJSIID assumes.
|
||||
*aRetVal = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::IsBuiltinClass(bool* aRetVal)
|
||||
{
|
||||
*aRetVal = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::IsMainProcessScriptableOnly(bool* aRetVal)
|
||||
{
|
||||
*aRetVal = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::GetParent(nsIInterfaceInfo** aParent)
|
||||
{
|
||||
*aParent = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::GetMethodCount(uint16_t* aCount)
|
||||
{
|
||||
// Pretend we don't have any methods.
|
||||
*aCount = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::GetConstantCount(uint16_t* aCount)
|
||||
{
|
||||
// We assume that we never have interfaces with more than UINT16_MAX
|
||||
// constants defined on them.
|
||||
uint16_t count = 0;
|
||||
|
||||
// NOTE: The structure of this loop must be kept in sync with the loop
|
||||
// in GetConstant.
|
||||
const mozilla::dom::NativePropertyHooks* propHooks = mNativePropHooks;
|
||||
do {
|
||||
const mozilla::dom::NativeProperties* props[] = {
|
||||
propHooks->mNativeProperties.regular,
|
||||
propHooks->mNativeProperties.chromeOnly
|
||||
};
|
||||
for (size_t i = 0; i < ArrayLength(props); ++i) {
|
||||
auto prop = props[i];
|
||||
if (prop && prop->HasConstants()) {
|
||||
for (auto cs = prop->Constants()->specs; cs->name; ++cs) {
|
||||
// We have found one constant here. We explicitly do not
|
||||
// bother calling isEnabled() here because it's OK to define
|
||||
// potentially extra constants on these shim interfaces.
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ((propHooks = propHooks->mProtoHooks));
|
||||
*aCount = count;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::GetMethodInfo(uint16_t aIndex, const nsXPTMethodInfo** aInfo)
|
||||
{
|
||||
MOZ_ASSERT(false, "This should never be called");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::GetMethodInfoForName(const char* aName, uint16_t* aIndex, const nsXPTMethodInfo** aInfo)
|
||||
{
|
||||
MOZ_ASSERT(false, "This should never be called");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::GetConstant(uint16_t aIndex, JS::MutableHandleValue aConstant,
|
||||
char** aName)
|
||||
{
|
||||
// We assume that we never have interfaces with more than UINT16_MAX
|
||||
// constants defined on them.
|
||||
uint16_t index = 0;
|
||||
|
||||
// NOTE: The structure of this loop must be kept in sync with the loop
|
||||
// in GetConstantCount.
|
||||
const mozilla::dom::NativePropertyHooks* propHooks = mNativePropHooks;
|
||||
do {
|
||||
const mozilla::dom::NativeProperties* props[] = {
|
||||
propHooks->mNativeProperties.regular,
|
||||
propHooks->mNativeProperties.chromeOnly
|
||||
};
|
||||
for (size_t i = 0; i < ArrayLength(props); ++i) {
|
||||
auto prop = props[i];
|
||||
if (prop && prop->HasConstants()) {
|
||||
for (auto cs = prop->Constants()->specs; cs->name; ++cs) {
|
||||
// We have found one constant here. We explicitly do not
|
||||
// bother calling isEnabled() here because it's OK to define
|
||||
// potentially extra constants on these shim interfaces.
|
||||
if (index == aIndex) {
|
||||
aConstant.set(cs->value);
|
||||
*aName = ToNewCString(nsDependentCString(cs->name));
|
||||
return NS_OK;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ((propHooks = propHooks->mProtoHooks));
|
||||
|
||||
// aIndex was bigger than the number of constants we have.
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::GetTypeForParam(uint16_t aInex, const nsXPTParamInfo* aParam, uint16_t aDimension, nsXPTType* aRetVal)
|
||||
{
|
||||
MOZ_ASSERT(false, "This should never be called");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::GetSizeIsArgNumberForParam(uint16_t aInex, const nsXPTParamInfo* aParam, uint16_t aDimension, uint8_t* aRetVal)
|
||||
{
|
||||
MOZ_ASSERT(false, "This should never be called");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::GetInterfaceIsArgNumberForParam(uint16_t aInex, const nsXPTParamInfo* aParam, uint8_t* aRetVal)
|
||||
{
|
||||
MOZ_ASSERT(false, "This should never be called");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::IsIID(const nsIID* aIID, bool* aRetVal)
|
||||
{
|
||||
*aRetVal = mIID.Equals(*aIID);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::GetNameShared(const char** aName)
|
||||
{
|
||||
*aName = mName.get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::GetIIDShared(const nsIID** aIID)
|
||||
{
|
||||
*aIID = &mIID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::IsFunction(bool* aRetVal)
|
||||
{
|
||||
*aRetVal = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ShimInterfaceInfo::HasAncestor(const nsIID* aIID, bool* aRetVal)
|
||||
{
|
||||
*aRetVal = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsresult)
|
||||
ShimInterfaceInfo::GetIIDForParamNoAlloc(uint16_t aIndex, const nsXPTParamInfo* aInfo, nsIID* aIID)
|
||||
{
|
||||
MOZ_ASSERT(false, "This should never be called");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=78:
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef ShimInterfaceInfo_h
|
||||
#define ShimInterfaceInfo_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsIInterfaceInfo.h"
|
||||
#include "nsString.h"
|
||||
#include "nsID.h"
|
||||
#include "nsTArray.h"
|
||||
#include "xptinfo.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "js/RootingAPI.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
struct NativePropertyHooks;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
class ShimInterfaceInfo final : public nsIInterfaceInfo
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIINTERFACEINFO
|
||||
|
||||
// Construct a ShimInterfaceInfo object if we have a shim available for aName.
|
||||
// Otherwise, returns nullptr.
|
||||
static already_AddRefed<ShimInterfaceInfo>
|
||||
MaybeConstruct(const char* aName, JSContext* cx);
|
||||
|
||||
private:
|
||||
ShimInterfaceInfo(const nsIID& aIID,
|
||||
const char* aName,
|
||||
const mozilla::dom::NativePropertyHooks* aNativePropHooks);
|
||||
|
||||
~ShimInterfaceInfo() {}
|
||||
|
||||
private:
|
||||
nsIID mIID;
|
||||
nsAutoCString mName;
|
||||
const mozilla::dom::NativePropertyHooks* mNativePropHooks;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,20 +0,0 @@
|
||||
/* jband - 03/24/00 - */
|
||||
|
||||
- DOCS
|
||||
- improve error handling
|
||||
- should some errors really be warnings?
|
||||
- should autoreg support additional channel to receive warnings so that
|
||||
an installer can decide whether or not to accept the consequences of
|
||||
leaving the newly installed files in place?
|
||||
- verification of interfaces (warnings and/or errors)
|
||||
- verify that repeated interfaces are identical in all ways
|
||||
- verify that interface names are always one-to-one with iids
|
||||
- check for truncated xpt files and version problems
|
||||
- http://bugzilla.mozilla.org/show_bug.cgi?id=33193
|
||||
- TESTS!
|
||||
- e.g. verify the merge stuff really works for various inputs.
|
||||
- we really need a set of .xpt and .zip files and code that does an array
|
||||
of autoreg and interfaceinof use activitities to test various corners
|
||||
of the system.
|
||||
- better autoreg logging
|
||||
- use only 32 bits for file size?
|
@ -1,93 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=4 et sw=4 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_XPTInterfaceInfoManager_h_
|
||||
#define mozilla_XPTInterfaceInfoManager_h_
|
||||
|
||||
#include "nsIInterfaceInfoManager.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/ReentrantMonitor.h"
|
||||
#include "nsDataHashtable.h"
|
||||
|
||||
template<typename T> class nsCOMArray;
|
||||
class nsIMemoryReporter;
|
||||
struct XPTInterfaceDescriptor;
|
||||
class xptiInterfaceEntry;
|
||||
class xptiInterfaceInfo;
|
||||
class xptiTypelibGuts;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class XPTInterfaceInfoManager final
|
||||
: public nsIInterfaceInfoManager
|
||||
, public nsIMemoryReporter
|
||||
{
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIINTERFACEINFOMANAGER
|
||||
NS_DECL_NSIMEMORYREPORTER
|
||||
|
||||
public:
|
||||
// GetSingleton() is infallible
|
||||
static XPTInterfaceInfoManager* GetSingleton();
|
||||
static void FreeInterfaceInfoManager();
|
||||
|
||||
void GetScriptableInterfaces(nsCOMArray<nsIInterfaceInfo>& aInterfaces);
|
||||
|
||||
static Mutex& GetResolveLock()
|
||||
{
|
||||
return GetSingleton()->mResolveLock;
|
||||
}
|
||||
|
||||
xptiInterfaceEntry* GetInterfaceEntryForIID(const nsIID *iid);
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
|
||||
|
||||
private:
|
||||
XPTInterfaceInfoManager();
|
||||
~XPTInterfaceInfoManager();
|
||||
|
||||
void InitMemoryReporter();
|
||||
|
||||
// idx is the index of this interface in the XPTHeader
|
||||
void VerifyAndAddEntryIfNew(const XPTInterfaceDescriptor* iface,
|
||||
uint16_t idx,
|
||||
xptiTypelibGuts* typelib);
|
||||
|
||||
private:
|
||||
|
||||
class xptiWorkingSet
|
||||
{
|
||||
public:
|
||||
xptiWorkingSet();
|
||||
~xptiWorkingSet();
|
||||
|
||||
void InvalidateInterfaceInfos();
|
||||
|
||||
// XXX make these private with accessors
|
||||
// mTableMonitor must be held across:
|
||||
// * any read from or write to mIIDTable or mNameTable
|
||||
// * any writing to the links between an xptiInterfaceEntry
|
||||
// and its xptiInterfaceInfo (mEntry/mInfo)
|
||||
mozilla::ReentrantMonitor mTableReentrantMonitor;
|
||||
nsDataHashtable<nsIDHashKey, xptiInterfaceEntry*> mIIDTable;
|
||||
nsDataHashtable<nsDepCharHashKey, xptiInterfaceEntry*> mNameTable;
|
||||
};
|
||||
|
||||
// XXX xptiInterfaceInfo want's to poke at the working set itself
|
||||
friend class ::xptiInterfaceInfo;
|
||||
friend class ::xptiInterfaceEntry;
|
||||
friend class ::xptiTypelibGuts;
|
||||
|
||||
xptiWorkingSet mWorkingSet;
|
||||
Mutex mResolveLock;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -5,33 +5,11 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'ShimInterfaceInfo.cpp',
|
||||
'xptiInterfaceInfo.cpp',
|
||||
'xptiInterfaceInfoManager.cpp',
|
||||
'xptiTypelibGuts.cpp',
|
||||
'xptiWorkingSet.cpp',
|
||||
]
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIInterfaceInfo.idl',
|
||||
'nsIInterfaceInfoManager.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'xpcom_xpti'
|
||||
|
||||
EXPORTS += [
|
||||
'xptinfo.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
'XPTInterfaceInfoManager.h',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/dom/base',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
|
||||
CXXFLAGS += ['-Wno-error=shadow']
|
||||
|
@ -1,88 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* The nsIInterfaceInfo public declaration. */
|
||||
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
// forward declaration of non-XPCOM types
|
||||
|
||||
[ptr] native nsXPTMethodInfoPtr(nsXPTMethodInfo);
|
||||
[ptr] native nsXPTParamInfoPtr(nsXPTParamInfo);
|
||||
native nsXPTType(nsXPTType);
|
||||
|
||||
// We bend the rules to do a [shared] nsIID (but this is never scriptable)
|
||||
[ptr] native nsIIDPtrShared(nsIID);
|
||||
|
||||
%{C++
|
||||
class nsXPTMethodInfo;
|
||||
class nsXPTParamInfo;
|
||||
class nsXPTType;
|
||||
%}
|
||||
|
||||
[builtinclass, uuid(3820e663-8e22-4789-b470-56bcf7083f2b)]
|
||||
interface nsIInterfaceInfo : nsISupports
|
||||
{
|
||||
readonly attribute string name;
|
||||
|
||||
boolean isScriptable();
|
||||
boolean isBuiltinClass();
|
||||
|
||||
readonly attribute nsIInterfaceInfo parent;
|
||||
|
||||
/**
|
||||
* These include counts for parent (and all ancestors).
|
||||
*/
|
||||
readonly attribute uint16_t methodCount;
|
||||
readonly attribute uint16_t constantCount;
|
||||
|
||||
/**
|
||||
* These include methods and constants for parent (and all ancestors).
|
||||
*
|
||||
* These do *not* make copies ***explicit bending of XPCOM rules***.
|
||||
*/
|
||||
|
||||
void getMethodInfo(in uint16_t index,
|
||||
[shared, retval] out nsXPTMethodInfoPtr info);
|
||||
|
||||
void getMethodInfoForName(in string methodName, out uint16_t index,
|
||||
[shared, retval] out nsXPTMethodInfoPtr info);
|
||||
|
||||
void getConstant(in uint16_t index,
|
||||
out jsval constant,
|
||||
out string name);
|
||||
|
||||
|
||||
/**
|
||||
* These do *not* make copies ***explicit bending of XPCOM rules***.
|
||||
*/
|
||||
|
||||
nsXPTType getTypeForParam(in uint16_t methodIndex,
|
||||
[const] in nsXPTParamInfoPtr param,
|
||||
in uint16_t dimension);
|
||||
|
||||
uint8_t getSizeIsArgNumberForParam(in uint16_t methodIndex,
|
||||
[const] in nsXPTParamInfoPtr param,
|
||||
in uint16_t dimension);
|
||||
|
||||
uint8_t getInterfaceIsArgNumberForParam(in uint16_t methodIndex,
|
||||
[const] in nsXPTParamInfoPtr param);
|
||||
|
||||
boolean isIID(in nsIIDPtr IID);
|
||||
|
||||
void getNameShared([shared,retval] out string name);
|
||||
void getIIDShared([shared,retval] out nsIIDPtrShared iid);
|
||||
|
||||
boolean isFunction();
|
||||
|
||||
boolean hasAncestor(in nsIIDPtr iid);
|
||||
|
||||
[notxpcom] nsresult getIIDForParamNoAlloc(in uint16_t methodIndex,
|
||||
[const] in nsXPTParamInfoPtr param,
|
||||
out nsIID iid);
|
||||
|
||||
boolean isMainProcessScriptableOnly();
|
||||
};
|
@ -1,28 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* The nsIInterfaceInfoManager public declaration. */
|
||||
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIInterfaceInfo;
|
||||
|
||||
[builtinclass, uuid(1d53d8d9-1d92-428f-b5cc-198b55e897d7)]
|
||||
interface nsIInterfaceInfoManager : nsISupports
|
||||
{
|
||||
nsIInterfaceInfo getInfoForIID(in nsIIDPtr iid);
|
||||
nsIInterfaceInfo getInfoForName(in string name);
|
||||
};
|
||||
|
||||
%{C++
|
||||
#define NS_INTERFACEINFOMANAGER_SERVICE_CID \
|
||||
{ /* 13bef784-f8e0-4f96-85c1-09f9ef4f9a19 */ \
|
||||
0x13bef784, 0xf8e0, 0x4f96, \
|
||||
{0x85, 0xc1, 0x09, 0xf9, 0xef, 0x4f, 0x9a, 0x19} }
|
||||
|
||||
#define NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID \
|
||||
"@mozilla.org/xpti/interfaceinfomanager-service;1"
|
||||
%}
|
@ -1,680 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* Implementation of xptiInterfaceEntry and xptiInterfaceInfo. */
|
||||
|
||||
#include "xptiprivate.h"
|
||||
#include "xpt_arena.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/XPTInterfaceInfoManager.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
#include "jsapi.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
/* static */ xptiInterfaceEntry*
|
||||
xptiInterfaceEntry::Create(const XPTInterfaceDescriptor* aIface,
|
||||
xptiTypelibGuts* aTypelib)
|
||||
{
|
||||
void* place = XPT_CALLOC8(gXPTIStructArena, sizeof(xptiInterfaceEntry));
|
||||
if (!place) {
|
||||
return nullptr;
|
||||
}
|
||||
return new (place) xptiInterfaceEntry(aIface, aTypelib);
|
||||
}
|
||||
|
||||
xptiInterfaceEntry::xptiInterfaceEntry(const XPTInterfaceDescriptor* aIface,
|
||||
xptiTypelibGuts* aTypelib)
|
||||
: mIID(aIface->mIID)
|
||||
, mDescriptor(aIface)
|
||||
, mTypelib(aTypelib)
|
||||
, mParent(nullptr)
|
||||
, mInfo(nullptr)
|
||||
, mMethodBaseIndex(0)
|
||||
, mConstantBaseIndex(0)
|
||||
, mFlags(0)
|
||||
, mName(aIface->Name())
|
||||
{
|
||||
SetResolvedState(PARTIALLY_RESOLVED);
|
||||
SetScriptableFlag(aIface->IsScriptable());
|
||||
SetBuiltinClassFlag(aIface->IsBuiltinClass());
|
||||
SetMainProcessScriptableOnlyFlag(aIface->IsMainProcessScriptableOnly());
|
||||
}
|
||||
|
||||
bool
|
||||
xptiInterfaceEntry::Resolve()
|
||||
{
|
||||
MutexAutoLock lock(XPTInterfaceInfoManager::GetResolveLock());
|
||||
return ResolveLocked();
|
||||
}
|
||||
|
||||
bool
|
||||
xptiInterfaceEntry::ResolveLocked()
|
||||
{
|
||||
int resolvedState = GetResolveState();
|
||||
|
||||
if(resolvedState == FULLY_RESOLVED)
|
||||
return true;
|
||||
if(resolvedState == RESOLVE_FAILED)
|
||||
return false;
|
||||
|
||||
NS_ASSERTION(GetResolveState() == PARTIALLY_RESOLVED, "bad state!");
|
||||
|
||||
// Finish out resolution by finding parent and Resolving it so
|
||||
// we can set the info we get from it.
|
||||
|
||||
uint16_t parent_index = mDescriptor->mParentInterface;
|
||||
|
||||
if(parent_index)
|
||||
{
|
||||
xptiInterfaceEntry* parent =
|
||||
mTypelib->GetEntryAt(parent_index - 1);
|
||||
|
||||
if(!parent || !parent->EnsureResolvedLocked())
|
||||
{
|
||||
SetResolvedState(RESOLVE_FAILED);
|
||||
return false;
|
||||
}
|
||||
|
||||
mParent = parent;
|
||||
if (parent->GetHasNotXPCOMFlag()) {
|
||||
SetHasNotXPCOMFlag();
|
||||
} else {
|
||||
for (uint16_t idx = 0; idx < mDescriptor->mNumMethods; ++idx) {
|
||||
const nsXPTMethodInfo* method = static_cast<const nsXPTMethodInfo*>(
|
||||
&mDescriptor->Method(idx));
|
||||
if (method->IsNotXPCOM()) {
|
||||
SetHasNotXPCOMFlag();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mMethodBaseIndex =
|
||||
parent->mMethodBaseIndex +
|
||||
parent->mDescriptor->mNumMethods;
|
||||
|
||||
mConstantBaseIndex =
|
||||
parent->mConstantBaseIndex +
|
||||
parent->mDescriptor->mNumConstants;
|
||||
|
||||
}
|
||||
|
||||
SetResolvedState(FULLY_RESOLVED);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************/
|
||||
// These non-virtual methods handle the delegated nsIInterfaceInfo methods.
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetName(char **name)
|
||||
{
|
||||
// It is not necessary to Resolve because this info is read from manifest.
|
||||
*name = moz_xstrdup(mName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetIID(nsIID **iid)
|
||||
{
|
||||
// It is not necessary to Resolve because this info is read from manifest.
|
||||
*iid = mIID.Clone();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::IsScriptable(bool* result)
|
||||
{
|
||||
// It is not necessary to Resolve because this info is read from manifest.
|
||||
*result = GetScriptableFlag();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::IsFunction(bool* result)
|
||||
{
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
*result = mDescriptor->IsFunction();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetMethodCount(uint16_t* count)
|
||||
{
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
*count = mMethodBaseIndex +
|
||||
mDescriptor->mNumMethods;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetConstantCount(uint16_t* count)
|
||||
{
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(!count)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
*count = mConstantBaseIndex +
|
||||
mDescriptor->mNumConstants;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetMethodInfo(uint16_t index, const nsXPTMethodInfo** info)
|
||||
{
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(index < mMethodBaseIndex)
|
||||
return mParent->GetMethodInfo(index, info);
|
||||
|
||||
if(index >= mMethodBaseIndex +
|
||||
mDescriptor->mNumMethods)
|
||||
{
|
||||
NS_ERROR("bad param");
|
||||
*info = nullptr;
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// else...
|
||||
*info = static_cast<const nsXPTMethodInfo*>
|
||||
(&mDescriptor->Method(index - mMethodBaseIndex));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetMethodInfoForName(const char* methodName, uint16_t *index,
|
||||
const nsXPTMethodInfo** result)
|
||||
{
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
// This is a slow algorithm, but this is not expected to be called much.
|
||||
for(uint16_t i = 0; i < mDescriptor->mNumMethods; ++i)
|
||||
{
|
||||
const nsXPTMethodInfo* info;
|
||||
info = static_cast<const nsXPTMethodInfo*>(&mDescriptor->Method(i));
|
||||
if (PL_strcmp(methodName, info->GetName()) == 0) {
|
||||
*index = i + mMethodBaseIndex;
|
||||
*result = info;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if(mParent)
|
||||
return mParent->GetMethodInfoForName(methodName, index, result);
|
||||
else
|
||||
{
|
||||
*index = 0;
|
||||
*result = 0;
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetConstant(uint16_t index, JS::MutableHandleValue constant,
|
||||
char** name)
|
||||
{
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(index < mConstantBaseIndex)
|
||||
return mParent->GetConstant(index, constant, name);
|
||||
|
||||
if(index >= mConstantBaseIndex +
|
||||
mDescriptor->mNumConstants)
|
||||
{
|
||||
NS_PRECONDITION(0, "bad param");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const auto& c = mDescriptor->Const(index - mConstantBaseIndex);
|
||||
AutoJSContext cx;
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
v.setUndefined();
|
||||
|
||||
switch (c.mType.mPrefix.mFlags) {
|
||||
case nsXPTType::T_I16:
|
||||
{
|
||||
v.setInt32(c.mValue.i16);
|
||||
break;
|
||||
}
|
||||
case nsXPTType::T_U16:
|
||||
{
|
||||
v.setInt32(c.mValue.ui16);
|
||||
break;
|
||||
}
|
||||
case nsXPTType::T_I32:
|
||||
{
|
||||
v = JS_NumberValue(c.mValue.i32);
|
||||
break;
|
||||
}
|
||||
case nsXPTType::T_U32:
|
||||
{
|
||||
v = JS_NumberValue(c.mValue.ui32);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
MOZ_ASSERT(false, "Invalid constant type found in interface");
|
||||
}
|
||||
}
|
||||
|
||||
constant.set(v);
|
||||
*name = ToNewCString(nsDependentCString(c.Name()));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// this is a private helper
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetInterfaceIndexForParam(uint16_t methodIndex,
|
||||
const nsXPTParamInfo* param,
|
||||
uint16_t* interfaceIndex)
|
||||
{
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(methodIndex < mMethodBaseIndex)
|
||||
return mParent->GetInterfaceIndexForParam(methodIndex, param,
|
||||
interfaceIndex);
|
||||
|
||||
if(methodIndex >= mMethodBaseIndex +
|
||||
mDescriptor->mNumMethods)
|
||||
{
|
||||
NS_ERROR("bad param");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const XPTTypeDescriptor *td = ¶m->mType;
|
||||
|
||||
while (td->Tag() == TD_ARRAY) {
|
||||
td = td->ArrayElementType();
|
||||
}
|
||||
|
||||
if (td->Tag() != TD_INTERFACE_TYPE) {
|
||||
NS_ERROR("not an interface");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
*interfaceIndex = td->InterfaceIndex();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetEntryForParam(uint16_t methodIndex,
|
||||
const nsXPTParamInfo * param,
|
||||
xptiInterfaceEntry** entry)
|
||||
{
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(methodIndex < mMethodBaseIndex)
|
||||
return mParent->GetEntryForParam(methodIndex, param, entry);
|
||||
|
||||
uint16_t interfaceIndex = 0;
|
||||
nsresult rv = GetInterfaceIndexForParam(methodIndex, param,
|
||||
&interfaceIndex);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
xptiInterfaceEntry* theEntry = mTypelib->GetEntryAt(interfaceIndex - 1);
|
||||
|
||||
// This can happen if a declared interface is not available at runtime.
|
||||
if(!theEntry)
|
||||
{
|
||||
*entry = nullptr;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*entry = theEntry;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<ShimInterfaceInfo>
|
||||
xptiInterfaceEntry::GetShimForParam(uint16_t methodIndex,
|
||||
const nsXPTParamInfo* param)
|
||||
{
|
||||
if(methodIndex < mMethodBaseIndex) {
|
||||
return mParent->GetShimForParam(methodIndex, param);
|
||||
}
|
||||
|
||||
uint16_t interfaceIndex = 0;
|
||||
nsresult rv = GetInterfaceIndexForParam(methodIndex, param,
|
||||
&interfaceIndex);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char* shimName = mTypelib->GetEntryNameAt(interfaceIndex - 1);
|
||||
RefPtr<ShimInterfaceInfo> shim =
|
||||
ShimInterfaceInfo::MaybeConstruct(shimName, nullptr);
|
||||
return shim.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetIIDForParamNoAlloc(uint16_t methodIndex,
|
||||
const nsXPTParamInfo * param,
|
||||
nsIID *iid)
|
||||
{
|
||||
xptiInterfaceEntry* entry;
|
||||
nsresult rv = GetEntryForParam(methodIndex, param, &entry);
|
||||
if (NS_FAILED(rv)) {
|
||||
RefPtr<ShimInterfaceInfo> shim = GetShimForParam(methodIndex, param);
|
||||
if (!shim) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
const nsIID* shimIID;
|
||||
DebugOnly<nsresult> rv2 = shim->GetIIDShared(&shimIID);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv2));
|
||||
*iid = *shimIID;
|
||||
return NS_OK;
|
||||
}
|
||||
*iid = entry->mIID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// this is a private helper
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetTypeInArray(const nsXPTParamInfo* param,
|
||||
uint16_t dimension,
|
||||
const XPTTypeDescriptor** type)
|
||||
{
|
||||
NS_ASSERTION(IsFullyResolved(), "bad state");
|
||||
|
||||
const XPTTypeDescriptor *td = ¶m->mType;
|
||||
|
||||
for (uint16_t i = 0; i < dimension; i++) {
|
||||
if (td->Tag() != TD_ARRAY) {
|
||||
NS_ERROR("bad dimension");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
td = td->ArrayElementType();
|
||||
}
|
||||
|
||||
*type = td;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetTypeForParam(uint16_t methodIndex,
|
||||
const nsXPTParamInfo* param,
|
||||
uint16_t dimension,
|
||||
nsXPTType* type)
|
||||
{
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(methodIndex < mMethodBaseIndex)
|
||||
return mParent->
|
||||
GetTypeForParam(methodIndex, param, dimension, type);
|
||||
|
||||
if(methodIndex >= mMethodBaseIndex +
|
||||
mDescriptor->mNumMethods)
|
||||
{
|
||||
NS_ERROR("bad index");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const XPTTypeDescriptor *td;
|
||||
|
||||
if(dimension) {
|
||||
nsresult rv = GetTypeInArray(param, dimension, &td);
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
td = ¶m->mType;
|
||||
|
||||
*type = nsXPTType(td->mPrefix);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetSizeIsArgNumberForParam(uint16_t methodIndex,
|
||||
const nsXPTParamInfo* param,
|
||||
uint16_t dimension,
|
||||
uint8_t* argnum)
|
||||
{
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(methodIndex < mMethodBaseIndex)
|
||||
return mParent->
|
||||
GetSizeIsArgNumberForParam(methodIndex, param, dimension, argnum);
|
||||
|
||||
if(methodIndex >= mMethodBaseIndex +
|
||||
mDescriptor->mNumMethods)
|
||||
{
|
||||
NS_ERROR("bad index");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const XPTTypeDescriptor *td;
|
||||
|
||||
if(dimension) {
|
||||
nsresult rv = GetTypeInArray(param, dimension, &td);
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
td = ¶m->mType;
|
||||
|
||||
// verify that this is a type that has size_is
|
||||
switch (td->Tag()) {
|
||||
case TD_ARRAY:
|
||||
case TD_PSTRING_SIZE_IS:
|
||||
case TD_PWSTRING_SIZE_IS:
|
||||
*argnum = td->ArgNum();
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("not a size_is");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetInterfaceIsArgNumberForParam(uint16_t methodIndex,
|
||||
const nsXPTParamInfo* param,
|
||||
uint8_t* argnum)
|
||||
{
|
||||
if(!EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(methodIndex < mMethodBaseIndex)
|
||||
return mParent->
|
||||
GetInterfaceIsArgNumberForParam(methodIndex, param, argnum);
|
||||
|
||||
if(methodIndex >= mMethodBaseIndex +
|
||||
mDescriptor->mNumMethods)
|
||||
{
|
||||
NS_ERROR("bad index");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const XPTTypeDescriptor *td = ¶m->mType;
|
||||
|
||||
while (td->Tag() == TD_ARRAY) {
|
||||
td = td->ArrayElementType();
|
||||
}
|
||||
|
||||
if (td->Tag() != TD_INTERFACE_IS_TYPE) {
|
||||
NS_ERROR("not an iid_is");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*argnum = td->ArgNum();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::IsIID(const nsIID * iid, bool *_retval)
|
||||
{
|
||||
// It is not necessary to Resolve because this info is read from manifest.
|
||||
*_retval = mIID.Equals(*iid);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetNameShared(const char **name)
|
||||
{
|
||||
// It is not necessary to Resolve because this info is read from manifest.
|
||||
*name = mName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::GetIIDShared(const nsIID * *iid)
|
||||
{
|
||||
// It is not necessary to Resolve because this info is read from manifest.
|
||||
*iid = &mIID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xptiInterfaceEntry::HasAncestor(const nsIID * iid, bool *_retval)
|
||||
{
|
||||
*_retval = false;
|
||||
|
||||
for(xptiInterfaceEntry* current = this;
|
||||
current;
|
||||
current = current->mParent)
|
||||
{
|
||||
if(current->mIID.Equals(*iid))
|
||||
{
|
||||
*_retval = true;
|
||||
break;
|
||||
}
|
||||
if(!current->EnsureResolved())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
|
||||
already_AddRefed<xptiInterfaceInfo>
|
||||
xptiInterfaceEntry::InterfaceInfo()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
XPTInterfaceInfoManager::GetSingleton()->mWorkingSet.mTableReentrantMonitor.
|
||||
AssertCurrentThreadIn();
|
||||
#endif
|
||||
|
||||
if(!mInfo)
|
||||
{
|
||||
mInfo = new xptiInterfaceInfo(this);
|
||||
}
|
||||
|
||||
RefPtr<xptiInterfaceInfo> info = mInfo;
|
||||
return info.forget();
|
||||
}
|
||||
|
||||
void
|
||||
xptiInterfaceEntry::LockedInvalidateInterfaceInfo()
|
||||
{
|
||||
if(mInfo)
|
||||
{
|
||||
mInfo->Invalidate();
|
||||
mInfo = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
xptiInterfaceInfo::BuildParent()
|
||||
{
|
||||
mozilla::ReentrantMonitorAutoEnter monitor(XPTInterfaceInfoManager::GetSingleton()->
|
||||
mWorkingSet.mTableReentrantMonitor);
|
||||
NS_ASSERTION(mEntry &&
|
||||
mEntry->IsFullyResolved() &&
|
||||
!mParent &&
|
||||
mEntry->Parent(),
|
||||
"bad BuildParent call");
|
||||
mParent = mEntry->Parent()->InterfaceInfo();
|
||||
return true;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE(xptiInterfaceInfo, nsIInterfaceInfo)
|
||||
|
||||
xptiInterfaceInfo::xptiInterfaceInfo(xptiInterfaceEntry* entry)
|
||||
: mEntry(entry)
|
||||
{
|
||||
}
|
||||
|
||||
xptiInterfaceInfo::~xptiInterfaceInfo()
|
||||
{
|
||||
NS_ASSERTION(!mEntry, "bad state in dtor");
|
||||
}
|
||||
|
||||
void
|
||||
xptiInterfaceInfo::Invalidate()
|
||||
{
|
||||
mParent = nullptr;
|
||||
mEntry = nullptr;
|
||||
}
|
||||
|
||||
MozExternalRefCountType
|
||||
xptiInterfaceInfo::AddRef(void)
|
||||
{
|
||||
nsrefcnt cnt = ++mRefCnt;
|
||||
NS_LOG_ADDREF(this, cnt, "xptiInterfaceInfo", sizeof(*this));
|
||||
return cnt;
|
||||
}
|
||||
|
||||
MozExternalRefCountType
|
||||
xptiInterfaceInfo::Release(void)
|
||||
{
|
||||
xptiInterfaceEntry* entry = mEntry;
|
||||
nsrefcnt cnt = --mRefCnt;
|
||||
NS_LOG_RELEASE(this, cnt, "xptiInterfaceInfo");
|
||||
if(!cnt)
|
||||
{
|
||||
mozilla::ReentrantMonitorAutoEnter monitor(XPTInterfaceInfoManager::
|
||||
GetSingleton()->mWorkingSet.
|
||||
mTableReentrantMonitor);
|
||||
|
||||
// If InterfaceInfo added and *released* a reference before we
|
||||
// acquired the monitor then 'this' might already be dead. In that
|
||||
// case we would not want to try to access any instance data. We
|
||||
// would want to bail immediately. If 'this' is already dead then the
|
||||
// entry will no longer have a pointer to 'this'. So, we can protect
|
||||
// ourselves from danger without more aggressive locking.
|
||||
if(entry && !entry->InterfaceInfoEquals(this))
|
||||
return 0;
|
||||
|
||||
// If InterfaceInfo added a reference before we acquired the monitor
|
||||
// then we want to bail out of here without destorying the object.
|
||||
if(mRefCnt)
|
||||
return 1;
|
||||
|
||||
if(mEntry)
|
||||
{
|
||||
mEntry->LockedInterfaceInfoDeathNotification();
|
||||
mEntry = nullptr;
|
||||
}
|
||||
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
@ -1,206 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=8 sts=4 et sw=4 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* Implementation of xptiInterfaceInfoManager. */
|
||||
|
||||
#include "mozilla/XPTInterfaceInfoManager.h"
|
||||
|
||||
#include "mozilla/FileUtils.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
|
||||
#include "xptiprivate.h"
|
||||
#include "nsDependentString.h"
|
||||
#include "nsString.h"
|
||||
#include "nsArrayEnumerator.h"
|
||||
#include "nsDirectoryService.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
NS_IMPL_ISUPPORTS(
|
||||
XPTInterfaceInfoManager,
|
||||
nsIInterfaceInfoManager,
|
||||
nsIMemoryReporter)
|
||||
|
||||
static StaticRefPtr<XPTInterfaceInfoManager> gInterfaceInfoManager;
|
||||
|
||||
size_t
|
||||
XPTInterfaceInfoManager::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
|
||||
{
|
||||
size_t n = aMallocSizeOf(this);
|
||||
ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
|
||||
// The entries themselves are allocated out of an arena accounted
|
||||
// for elsewhere, so don't measure them
|
||||
n += mWorkingSet.mIIDTable.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mWorkingSet.mNameTable.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
return n;
|
||||
}
|
||||
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF(XPTIMallocSizeOf)
|
||||
|
||||
NS_IMETHODIMP
|
||||
XPTInterfaceInfoManager::CollectReports(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData, bool aAnonymize)
|
||||
{
|
||||
size_t amount = SizeOfIncludingThis(XPTIMallocSizeOf);
|
||||
|
||||
// Measure gXPTIStructArena here, too. This is a bit grotty because it
|
||||
// doesn't belong to the XPTIInterfaceInfoManager, but there's no
|
||||
// obviously better place to measure it.
|
||||
amount += XPT_SizeOfArenaIncludingThis(gXPTIStructArena, XPTIMallocSizeOf);
|
||||
|
||||
MOZ_COLLECT_REPORT(
|
||||
"explicit/xpti-working-set", KIND_HEAP, UNITS_BYTES, amount,
|
||||
"Memory used by the XPCOM typelib system.");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
XPTInterfaceInfoManager*
|
||||
XPTInterfaceInfoManager::GetSingleton()
|
||||
{
|
||||
if (!gInterfaceInfoManager) {
|
||||
gInterfaceInfoManager = new XPTInterfaceInfoManager();
|
||||
gInterfaceInfoManager->InitMemoryReporter();
|
||||
}
|
||||
return gInterfaceInfoManager;
|
||||
}
|
||||
|
||||
void
|
||||
XPTInterfaceInfoManager::FreeInterfaceInfoManager()
|
||||
{
|
||||
gInterfaceInfoManager = nullptr;
|
||||
}
|
||||
|
||||
XPTInterfaceInfoManager::XPTInterfaceInfoManager()
|
||||
: mWorkingSet(),
|
||||
mResolveLock("XPTInterfaceInfoManager.mResolveLock")
|
||||
{
|
||||
xptiTypelibGuts* typelib = xptiTypelibGuts::Create();
|
||||
|
||||
ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
|
||||
for (uint16_t k = 0; k < XPTHeader::kNumInterfaces; k++) {
|
||||
VerifyAndAddEntryIfNew(XPTHeader::kInterfaces + k, k, typelib);
|
||||
}
|
||||
}
|
||||
|
||||
XPTInterfaceInfoManager::~XPTInterfaceInfoManager()
|
||||
{
|
||||
// We only do this on shutdown of the service.
|
||||
mWorkingSet.InvalidateInterfaceInfos();
|
||||
|
||||
UnregisterWeakMemoryReporter(this);
|
||||
}
|
||||
|
||||
void
|
||||
XPTInterfaceInfoManager::InitMemoryReporter()
|
||||
{
|
||||
RegisterWeakMemoryReporter(this);
|
||||
}
|
||||
|
||||
void
|
||||
XPTInterfaceInfoManager::VerifyAndAddEntryIfNew(const XPTInterfaceDescriptor* iface,
|
||||
uint16_t idx,
|
||||
xptiTypelibGuts* typelib)
|
||||
{
|
||||
static const nsID zeroIID =
|
||||
{ 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } };
|
||||
|
||||
if (iface->mIID.Equals(zeroIID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The number of maximum methods is not arbitrary. It is the same value as
|
||||
// in xpcom/reflect/xptcall/genstubs.pl; do not change this value
|
||||
// without changing that one or you WILL see problems.
|
||||
if (iface->mNumMethods > 250 && !iface->IsBuiltinClass()) {
|
||||
NS_ASSERTION(0, "Too many methods to handle for the stub, cannot load");
|
||||
fprintf(stderr, "ignoring too large interface: %s\n", iface->Name());
|
||||
return;
|
||||
}
|
||||
|
||||
mWorkingSet.mTableReentrantMonitor.AssertCurrentThreadIn();
|
||||
xptiInterfaceEntry* entry = mWorkingSet.mIIDTable.Get(iface->mIID);
|
||||
if (entry) {
|
||||
// XXX validate this info to find possible inconsistencies
|
||||
return;
|
||||
}
|
||||
|
||||
// Build a new xptiInterfaceEntry object and hook it up.
|
||||
|
||||
entry = xptiInterfaceEntry::Create(iface, typelib);
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
mWorkingSet.mIIDTable.Put(entry->IID(), entry);
|
||||
mWorkingSet.mNameTable.Put(entry->GetTheName(), entry);
|
||||
|
||||
typelib->SetEntryAt(idx, entry);
|
||||
}
|
||||
|
||||
// this is a private helper
|
||||
static nsresult
|
||||
EntryToInfo(xptiInterfaceEntry* entry, nsIInterfaceInfo **_retval)
|
||||
{
|
||||
if (!entry) {
|
||||
*_retval = nullptr;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
RefPtr<xptiInterfaceInfo> info = entry->InterfaceInfo();
|
||||
info.forget(_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
xptiInterfaceEntry*
|
||||
XPTInterfaceInfoManager::GetInterfaceEntryForIID(const nsIID *iid)
|
||||
{
|
||||
ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
|
||||
return mWorkingSet.mIIDTable.Get(*iid);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XPTInterfaceInfoManager::GetInfoForIID(const nsIID * iid, nsIInterfaceInfo **_retval)
|
||||
{
|
||||
NS_ASSERTION(iid, "bad param");
|
||||
NS_ASSERTION(_retval, "bad param");
|
||||
|
||||
ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
|
||||
xptiInterfaceEntry* entry = mWorkingSet.mIIDTable.Get(*iid);
|
||||
return EntryToInfo(entry, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XPTInterfaceInfoManager::GetInfoForName(const char *name, nsIInterfaceInfo **_retval)
|
||||
{
|
||||
NS_ASSERTION(name, "bad param");
|
||||
NS_ASSERTION(_retval, "bad param");
|
||||
|
||||
ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
|
||||
xptiInterfaceEntry* entry = mWorkingSet.mNameTable.Get(name);
|
||||
return EntryToInfo(entry, _retval);
|
||||
}
|
||||
|
||||
void
|
||||
XPTInterfaceInfoManager::GetScriptableInterfaces(nsCOMArray<nsIInterfaceInfo>& aInterfaces)
|
||||
{
|
||||
// I didn't want to incur the size overhead of using nsHashtable just to
|
||||
// make building an enumerator easier. So, this code makes a snapshot of
|
||||
// the table using an nsCOMArray and builds an enumerator for that.
|
||||
// We can afford this transient cost.
|
||||
|
||||
ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
|
||||
aInterfaces.SetCapacity(mWorkingSet.mNameTable.Count());
|
||||
for (auto iter = mWorkingSet.mNameTable.Iter(); !iter.Done(); iter.Next()) {
|
||||
xptiInterfaceEntry* entry = iter.UserData();
|
||||
if (entry->GetScriptableFlag()) {
|
||||
nsCOMPtr<nsIInterfaceInfo> ii = entry->InterfaceInfo();
|
||||
aInterfaces.AppendElement(ii);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* Implementation of xptiTypelibGuts. */
|
||||
|
||||
#include "xptiprivate.h"
|
||||
#include "xpt_arena.h"
|
||||
#include "mozilla/XPTInterfaceInfoManager.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// Ensure through static analysis that xptiTypelibGuts won't have a vtable.
|
||||
template <class T>
|
||||
class MOZ_NEEDS_NO_VTABLE_TYPE CheckNoVTable
|
||||
{
|
||||
};
|
||||
CheckNoVTable<xptiTypelibGuts> gChecker;
|
||||
|
||||
// static
|
||||
xptiTypelibGuts*
|
||||
xptiTypelibGuts::Create()
|
||||
{
|
||||
size_t n = sizeof(xptiTypelibGuts) +
|
||||
sizeof(xptiInterfaceEntry*) * (XPTHeader::kNumInterfaces - 1);
|
||||
void* place = XPT_CALLOC8(gXPTIStructArena, n);
|
||||
if (!place)
|
||||
return nullptr;
|
||||
return new(place) xptiTypelibGuts();
|
||||
}
|
||||
|
||||
xptiInterfaceEntry*
|
||||
xptiTypelibGuts::GetEntryAt(uint16_t i)
|
||||
{
|
||||
static const nsID zeroIID =
|
||||
{ 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } };
|
||||
|
||||
NS_ASSERTION(i < GetEntryCount(), "bad index");
|
||||
|
||||
xptiInterfaceEntry* r = mEntryArray[i];
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
const XPTInterfaceDescriptor* iface = XPTHeader::kInterfaces + i;
|
||||
|
||||
XPTInterfaceInfoManager::xptiWorkingSet& set =
|
||||
XPTInterfaceInfoManager::GetSingleton()->mWorkingSet;
|
||||
|
||||
{
|
||||
ReentrantMonitorAutoEnter monitor(set.mTableReentrantMonitor);
|
||||
if (iface->mIID.Equals(zeroIID))
|
||||
r = set.mNameTable.Get(iface->Name());
|
||||
else
|
||||
r = set.mIIDTable.Get(iface->mIID);
|
||||
}
|
||||
|
||||
if (r)
|
||||
SetEntryAt(i, r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
const char*
|
||||
xptiTypelibGuts::GetEntryNameAt(uint16_t i)
|
||||
{
|
||||
NS_ASSERTION(i < GetEntryCount(), "bad index");
|
||||
|
||||
const XPTInterfaceDescriptor* iface = XPTHeader::kInterfaces + i;
|
||||
|
||||
return iface->Name();
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=8 sts=4 et sw=4 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* Implementation of xptiWorkingSet. */
|
||||
|
||||
#include "mozilla/XPTInterfaceInfoManager.h"
|
||||
|
||||
#include "xptiprivate.h"
|
||||
#include "nsString.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
static const size_t XPTI_ARENA8_BLOCK_SIZE = 16 * 1024;
|
||||
static const size_t XPTI_ARENA1_BLOCK_SIZE = 8 * 1024;
|
||||
|
||||
static const uint32_t XPTI_HASHTABLE_LENGTH = 1024;
|
||||
|
||||
XPTInterfaceInfoManager::xptiWorkingSet::xptiWorkingSet()
|
||||
: mTableReentrantMonitor("xptiWorkingSet::mTableReentrantMonitor")
|
||||
, mIIDTable(XPTI_HASHTABLE_LENGTH)
|
||||
, mNameTable(XPTI_HASHTABLE_LENGTH)
|
||||
{
|
||||
MOZ_COUNT_CTOR(xptiWorkingSet);
|
||||
|
||||
gXPTIStructArena = XPT_NewArena(XPTI_ARENA8_BLOCK_SIZE,
|
||||
XPTI_ARENA1_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
void
|
||||
XPTInterfaceInfoManager::xptiWorkingSet::InvalidateInterfaceInfos()
|
||||
{
|
||||
ReentrantMonitorAutoEnter monitor(mTableReentrantMonitor);
|
||||
for (auto iter = mNameTable.Iter(); !iter.Done(); iter.Next()) {
|
||||
xptiInterfaceEntry* entry = iter.UserData();
|
||||
entry->LockedInvalidateInterfaceInfo();
|
||||
}
|
||||
}
|
||||
|
||||
XPTInterfaceInfoManager::xptiWorkingSet::~xptiWorkingSet()
|
||||
{
|
||||
MOZ_COUNT_DTOR(xptiWorkingSet);
|
||||
|
||||
// Only destroy the arena if we're doing leak stats. Why waste shutdown
|
||||
// time touching pages if we don't have to?
|
||||
#ifdef NS_FREE_PERMANENT_DATA
|
||||
XPT_DestroyArena(gXPTIStructArena);
|
||||
#endif
|
||||
}
|
||||
|
||||
XPTArena* gXPTIStructArena;
|
@ -1,363 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* Library-private header for Interface Info system. */
|
||||
|
||||
#ifndef xptiprivate_h___
|
||||
#define xptiprivate_h___
|
||||
|
||||
#include "nscore.h"
|
||||
#include <new>
|
||||
#include "nsISupports.h"
|
||||
|
||||
// this after nsISupports, to pick up IID
|
||||
// so that xpt stuff doesn't try to define it itself...
|
||||
#include "xpt_struct.h"
|
||||
|
||||
#include "nsIInterfaceInfo.h"
|
||||
#include "nsIInterfaceInfoManager.h"
|
||||
#include "xptinfo.h"
|
||||
#include "ShimInterfaceInfo.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIDirectoryService.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsIWeakReference.h"
|
||||
|
||||
#include "mozilla/ReentrantMonitor.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "js/TypeDecls.h"
|
||||
|
||||
#include "nsCRT.h"
|
||||
#include "nsMemory.h"
|
||||
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsQuickSort.h"
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "plstr.h"
|
||||
#include "prprf.h"
|
||||
#include "prio.h"
|
||||
#include "prtime.h"
|
||||
#include "prenv.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
class xptiInterfaceInfo;
|
||||
class xptiInterfaceEntry;
|
||||
class xptiTypelibGuts;
|
||||
|
||||
struct XPTArena;
|
||||
extern XPTArena* gXPTIStructArena;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
// No virtuals.
|
||||
// These are always constructed in the struct arena using placement new.
|
||||
// dtor need not be called.
|
||||
|
||||
class xptiTypelibGuts
|
||||
{
|
||||
public:
|
||||
static xptiTypelibGuts* Create();
|
||||
|
||||
uint16_t GetEntryCount() const { return XPTHeader::kNumInterfaces; }
|
||||
|
||||
void SetEntryAt(uint16_t i, xptiInterfaceEntry* ptr)
|
||||
{
|
||||
NS_ASSERTION(i < GetEntryCount(),"bad param!");
|
||||
mEntryArray[i] = ptr;
|
||||
}
|
||||
|
||||
xptiInterfaceEntry* GetEntryAt(uint16_t i);
|
||||
const char* GetEntryNameAt(uint16_t i);
|
||||
|
||||
private:
|
||||
xptiTypelibGuts() = default;
|
||||
~xptiTypelibGuts();
|
||||
|
||||
private:
|
||||
xptiInterfaceEntry* mEntryArray[1]; // Always last. Sized to fit.
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
// This class exists to help xptiInterfaceInfo store a 4-state (2 bit) value
|
||||
// and a set of bitflags in one 8bit value. See below.
|
||||
|
||||
class xptiInfoFlags
|
||||
{
|
||||
enum {STATE_MASK = 3};
|
||||
public:
|
||||
explicit xptiInfoFlags(uint8_t n) : mData(n) {}
|
||||
xptiInfoFlags(const xptiInfoFlags& r) : mData(r.mData) {}
|
||||
|
||||
static uint8_t GetStateMask()
|
||||
{return uint8_t(STATE_MASK);}
|
||||
|
||||
void Clear()
|
||||
{mData = 0;}
|
||||
|
||||
uint8_t GetData() const
|
||||
{return mData;}
|
||||
|
||||
uint8_t GetState() const
|
||||
{return mData & GetStateMask();}
|
||||
|
||||
void SetState(uint8_t state)
|
||||
{mData &= ~GetStateMask(); mData |= state;}
|
||||
|
||||
void SetFlagBit(uint8_t flag, bool on)
|
||||
{if(on)
|
||||
mData |= ~GetStateMask() & flag;
|
||||
else
|
||||
mData &= GetStateMask() | ~flag;}
|
||||
|
||||
bool GetFlagBit(uint8_t flag) const
|
||||
{return (mData & flag) ? true : false;}
|
||||
|
||||
private:
|
||||
uint8_t mData;
|
||||
};
|
||||
|
||||
/****************************************************/
|
||||
|
||||
// No virtual methods.
|
||||
// We always create in the struct arena and construct using "placement new".
|
||||
// No members need dtor calls.
|
||||
|
||||
class xptiInterfaceEntry
|
||||
{
|
||||
public:
|
||||
static xptiInterfaceEntry* Create(const XPTInterfaceDescriptor* aIface,
|
||||
xptiTypelibGuts* aTypelib);
|
||||
|
||||
enum {
|
||||
PARTIALLY_RESOLVED = 1,
|
||||
FULLY_RESOLVED = 2,
|
||||
RESOLVE_FAILED = 3
|
||||
};
|
||||
|
||||
// Additional bit flags...
|
||||
enum {SCRIPTABLE = 4, BUILTINCLASS = 8, HASNOTXPCOM = 16,
|
||||
MAIN_PROCESS_SCRIPTABLE_ONLY = 32};
|
||||
|
||||
uint8_t GetResolveState() const {return mFlags.GetState();}
|
||||
|
||||
bool IsFullyResolved() const
|
||||
{return GetResolveState() == (uint8_t) FULLY_RESOLVED;}
|
||||
|
||||
void SetScriptableFlag(bool on)
|
||||
{mFlags.SetFlagBit(uint8_t(SCRIPTABLE),on);}
|
||||
bool GetScriptableFlag() const
|
||||
{return mFlags.GetFlagBit(uint8_t(SCRIPTABLE));}
|
||||
void SetBuiltinClassFlag(bool on)
|
||||
{mFlags.SetFlagBit(uint8_t(BUILTINCLASS),on);}
|
||||
bool GetBuiltinClassFlag() const
|
||||
{return mFlags.GetFlagBit(uint8_t(BUILTINCLASS));}
|
||||
void SetMainProcessScriptableOnlyFlag(bool on)
|
||||
{mFlags.SetFlagBit(uint8_t(MAIN_PROCESS_SCRIPTABLE_ONLY),on);}
|
||||
bool GetMainProcessScriptableOnlyFlag() const
|
||||
{return mFlags.GetFlagBit(uint8_t(MAIN_PROCESS_SCRIPTABLE_ONLY));}
|
||||
|
||||
|
||||
// AddRef/Release are special and are not considered for the NOTXPCOM flag.
|
||||
void SetHasNotXPCOMFlag()
|
||||
{
|
||||
mFlags.SetFlagBit(HASNOTXPCOM, true);
|
||||
}
|
||||
bool GetHasNotXPCOMFlag() const
|
||||
{
|
||||
return mFlags.GetFlagBit(HASNOTXPCOM);
|
||||
}
|
||||
|
||||
const nsID* GetTheIID() const {return &mIID;}
|
||||
const char* GetTheName() const {return mName;}
|
||||
|
||||
bool EnsureResolved()
|
||||
{return IsFullyResolved() ? true : Resolve();}
|
||||
|
||||
already_AddRefed<xptiInterfaceInfo> InterfaceInfo();
|
||||
bool InterfaceInfoEquals(const xptiInterfaceInfo* info) const
|
||||
{return info == mInfo;}
|
||||
|
||||
void LockedInvalidateInterfaceInfo();
|
||||
void LockedInterfaceInfoDeathNotification() {mInfo = nullptr;}
|
||||
|
||||
xptiInterfaceEntry* Parent() const {
|
||||
NS_ASSERTION(IsFullyResolved(), "Parent() called while not resolved?");
|
||||
return mParent;
|
||||
}
|
||||
|
||||
const nsID& IID() const { return mIID; }
|
||||
|
||||
//////////////////////
|
||||
// These non-virtual methods handle the delegated nsIInterfaceInfo methods.
|
||||
|
||||
nsresult GetName(char * *aName);
|
||||
nsresult GetIID(nsIID * *aIID);
|
||||
nsresult IsScriptable(bool *_retval);
|
||||
nsresult IsBuiltinClass(bool *_retval) {
|
||||
*_retval = GetBuiltinClassFlag();
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult IsMainProcessScriptableOnly(bool *_retval) {
|
||||
*_retval = GetMainProcessScriptableOnlyFlag();
|
||||
return NS_OK;
|
||||
}
|
||||
// Except this one.
|
||||
//nsresult GetParent(nsIInterfaceInfo * *aParent);
|
||||
nsresult GetMethodCount(uint16_t *aMethodCount);
|
||||
nsresult GetConstantCount(uint16_t *aConstantCount);
|
||||
nsresult GetMethodInfo(uint16_t index, const nsXPTMethodInfo * *info);
|
||||
nsresult GetMethodInfoForName(const char *methodName, uint16_t *index, const nsXPTMethodInfo * *info);
|
||||
nsresult GetConstant(uint16_t index, JS::MutableHandleValue, char** constant);
|
||||
nsresult GetTypeForParam(uint16_t methodIndex, const nsXPTParamInfo * param, uint16_t dimension, nsXPTType *_retval);
|
||||
nsresult GetSizeIsArgNumberForParam(uint16_t methodIndex, const nsXPTParamInfo * param, uint16_t dimension, uint8_t *_retval);
|
||||
nsresult GetInterfaceIsArgNumberForParam(uint16_t methodIndex, const nsXPTParamInfo * param, uint8_t *_retval);
|
||||
nsresult IsIID(const nsIID * IID, bool *_retval);
|
||||
nsresult GetNameShared(const char **name);
|
||||
nsresult GetIIDShared(const nsIID * *iid);
|
||||
nsresult IsFunction(bool *_retval);
|
||||
nsresult HasAncestor(const nsIID * iid, bool *_retval);
|
||||
nsresult GetIIDForParamNoAlloc(uint16_t methodIndex, const nsXPTParamInfo * param, nsIID *iid);
|
||||
|
||||
private:
|
||||
xptiInterfaceEntry(const XPTInterfaceDescriptor* aIface,
|
||||
xptiTypelibGuts* aTypelib);
|
||||
~xptiInterfaceEntry();
|
||||
|
||||
void SetResolvedState(int state)
|
||||
{mFlags.SetState(uint8_t(state));}
|
||||
|
||||
bool Resolve();
|
||||
|
||||
// We only call these "*Locked" variants after locking. This is done to
|
||||
// allow reentrace as files are loaded and various interfaces resolved
|
||||
// without having to worry about the locked state.
|
||||
|
||||
bool EnsureResolvedLocked()
|
||||
{return IsFullyResolved() ? true : ResolveLocked();}
|
||||
bool ResolveLocked();
|
||||
|
||||
// private helpers
|
||||
|
||||
nsresult GetEntryForParam(uint16_t methodIndex,
|
||||
const nsXPTParamInfo * param,
|
||||
xptiInterfaceEntry** entry);
|
||||
|
||||
nsresult GetTypeInArray(const nsXPTParamInfo* param,
|
||||
uint16_t dimension,
|
||||
const XPTTypeDescriptor** type);
|
||||
|
||||
nsresult GetInterfaceIndexForParam(uint16_t methodIndex,
|
||||
const nsXPTParamInfo* param,
|
||||
uint16_t* interfaceIndex);
|
||||
|
||||
already_AddRefed<ShimInterfaceInfo>
|
||||
GetShimForParam(uint16_t methodIndex, const nsXPTParamInfo* param);
|
||||
|
||||
private:
|
||||
nsID mIID;
|
||||
const XPTInterfaceDescriptor* mDescriptor;
|
||||
|
||||
xptiTypelibGuts* mTypelib;
|
||||
|
||||
xptiInterfaceEntry* mParent; // Valid only when fully resolved
|
||||
|
||||
xptiInterfaceInfo* MOZ_UNSAFE_REF("The safety of this pointer is ensured "
|
||||
"by the semantics of xptiWorkingSet.")
|
||||
mInfo; // May come and go.
|
||||
|
||||
uint16_t mMethodBaseIndex;
|
||||
uint16_t mConstantBaseIndex;
|
||||
|
||||
xptiInfoFlags mFlags;
|
||||
|
||||
const char* mName;
|
||||
};
|
||||
|
||||
class xptiInterfaceInfo final : public nsIInterfaceInfo
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
// Use delegation to implement (most!) of nsIInterfaceInfo.
|
||||
NS_IMETHOD GetName(char * *aName) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetName(aName); }
|
||||
NS_IMETHOD IsScriptable(bool *_retval) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->IsScriptable(_retval); }
|
||||
NS_IMETHOD IsBuiltinClass(bool *_retval) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->IsBuiltinClass(_retval); }
|
||||
NS_IMETHOD IsMainProcessScriptableOnly(bool *_retval) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->IsMainProcessScriptableOnly(_retval); }
|
||||
// Except this one.
|
||||
NS_IMETHOD GetParent(nsIInterfaceInfo * *aParent) override
|
||||
{
|
||||
if(!EnsureResolved() || !EnsureParent())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
NS_IF_ADDREF(*aParent = mParent);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD GetMethodCount(uint16_t *aMethodCount) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetMethodCount(aMethodCount); }
|
||||
NS_IMETHOD GetConstantCount(uint16_t *aConstantCount) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetConstantCount(aConstantCount); }
|
||||
NS_IMETHOD GetMethodInfo(uint16_t index, const nsXPTMethodInfo * *info) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetMethodInfo(index, info); }
|
||||
NS_IMETHOD GetMethodInfoForName(const char *methodName, uint16_t *index, const nsXPTMethodInfo * *info) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetMethodInfoForName(methodName, index, info); }
|
||||
NS_IMETHOD GetConstant(uint16_t index, JS::MutableHandleValue constant, char** name) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetConstant(index, constant, name); }
|
||||
NS_IMETHOD GetTypeForParam(uint16_t methodIndex, const nsXPTParamInfo * param, uint16_t dimension, nsXPTType *_retval) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetTypeForParam(methodIndex, param, dimension, _retval); }
|
||||
NS_IMETHOD GetSizeIsArgNumberForParam(uint16_t methodIndex, const nsXPTParamInfo * param, uint16_t dimension, uint8_t *_retval) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetSizeIsArgNumberForParam(methodIndex, param, dimension, _retval); }
|
||||
NS_IMETHOD GetInterfaceIsArgNumberForParam(uint16_t methodIndex, const nsXPTParamInfo * param, uint8_t *_retval) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetInterfaceIsArgNumberForParam(methodIndex, param, _retval); }
|
||||
NS_IMETHOD IsIID(const nsIID * IID, bool *_retval) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->IsIID(IID, _retval); }
|
||||
NS_IMETHOD GetNameShared(const char **name) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetNameShared(name); }
|
||||
NS_IMETHOD GetIIDShared(const nsIID * *iid) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetIIDShared(iid); }
|
||||
NS_IMETHOD IsFunction(bool *_retval) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->IsFunction(_retval); }
|
||||
NS_IMETHOD HasAncestor(const nsIID * iid, bool *_retval) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->HasAncestor(iid, _retval); }
|
||||
NS_IMETHOD GetIIDForParamNoAlloc(uint16_t methodIndex, const nsXPTParamInfo * param, nsIID *iid) override { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetIIDForParamNoAlloc(methodIndex, param, iid); }
|
||||
|
||||
public:
|
||||
explicit xptiInterfaceInfo(xptiInterfaceEntry* entry);
|
||||
|
||||
void Invalidate();
|
||||
|
||||
private:
|
||||
|
||||
~xptiInterfaceInfo();
|
||||
|
||||
// Note that mParent might still end up as nullptr if we don't have one.
|
||||
bool EnsureParent()
|
||||
{
|
||||
NS_ASSERTION(mEntry && mEntry->IsFullyResolved(), "bad EnsureParent call");
|
||||
return mParent || !mEntry->Parent() || BuildParent();
|
||||
}
|
||||
|
||||
bool EnsureResolved()
|
||||
{
|
||||
return mEntry && mEntry->EnsureResolved();
|
||||
}
|
||||
|
||||
bool BuildParent();
|
||||
|
||||
xptiInterfaceInfo(); // not implemented
|
||||
|
||||
private:
|
||||
xptiInterfaceEntry* mEntry;
|
||||
RefPtr<xptiInterfaceInfo> mParent;
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#endif /* xptiprivate_h___ */
|
@ -4,31 +4,4 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
Library('xpt')
|
||||
|
||||
DIRS += ['tools']
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'xpt_arena.cpp',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'!XPTInfo.cpp',
|
||||
]
|
||||
|
||||
EXPORTS += [
|
||||
'xpt_arena.h',
|
||||
'xpt_struct.h',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'!/xpcom/base',
|
||||
'/xpcom/base',
|
||||
]
|
||||
|
||||
if CONFIG['CC_TYPE'] in ('msvc', 'clang-cl'):
|
||||
CFLAGS += ['-Zl']
|
||||
|
||||
DIST_INSTALL = True
|
||||
|
@ -1,188 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=8 sts=4 et sw=4 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* Quick arena hack for xpt. */
|
||||
|
||||
/* XXX This exists because we don't want to drag in NSPR. It *seemed*
|
||||
* to make more sense to write a quick and dirty arena than to clone
|
||||
* plarena (like js/src did). This is not optimal, but it works.
|
||||
*/
|
||||
|
||||
#include "xpt_arena.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/****************************************************/
|
||||
|
||||
/* Block header for each block in the arena */
|
||||
struct BLK_HDR
|
||||
{
|
||||
BLK_HDR *next;
|
||||
};
|
||||
|
||||
#define XPT_MIN_BLOCK_SIZE 32
|
||||
|
||||
/* XXX this is lame. Should clone the code to do this bitwise */
|
||||
#define ALIGN_RND(s,a) ((a)==1?(s):((((s)+(a)-1)/(a))*(a)))
|
||||
|
||||
struct XPTSubArena
|
||||
{
|
||||
BLK_HDR *first;
|
||||
uint8_t *next;
|
||||
size_t space;
|
||||
size_t block_size;
|
||||
};
|
||||
|
||||
struct XPTArena
|
||||
{
|
||||
// We have one sub-arena with 8-byte alignment for most allocations, and
|
||||
// one with 1-byte alignment for C string allocations. The latter sub-arena
|
||||
// avoids significant amounts of unnecessary padding between C strings.
|
||||
XPTSubArena subarena8;
|
||||
XPTSubArena subarena1;
|
||||
};
|
||||
|
||||
XPTArena*
|
||||
XPT_NewArena(size_t block_size8, size_t block_size1)
|
||||
{
|
||||
XPTArena *arena = static_cast<XPTArena*>(calloc(1, sizeof(XPTArena)));
|
||||
if (arena) {
|
||||
if (block_size8 < XPT_MIN_BLOCK_SIZE)
|
||||
block_size8 = XPT_MIN_BLOCK_SIZE;
|
||||
arena->subarena8.block_size = ALIGN_RND(block_size8, 8);
|
||||
|
||||
if (block_size1 < XPT_MIN_BLOCK_SIZE)
|
||||
block_size1 = XPT_MIN_BLOCK_SIZE;
|
||||
arena->subarena1.block_size = block_size1;
|
||||
}
|
||||
return arena;
|
||||
}
|
||||
|
||||
static void
|
||||
DestroySubArena(XPTSubArena *subarena)
|
||||
{
|
||||
BLK_HDR* cur = subarena->first;
|
||||
while (cur) {
|
||||
BLK_HDR* next = cur->next;
|
||||
free(cur);
|
||||
cur = next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XPT_DestroyArena(XPTArena *arena)
|
||||
{
|
||||
DestroySubArena(&arena->subarena8);
|
||||
DestroySubArena(&arena->subarena1);
|
||||
free(arena);
|
||||
}
|
||||
|
||||
/*
|
||||
* Our alignment rule is that we always round up the size of each allocation
|
||||
* so that the 'arena->next' pointer one will point to properly aligned space.
|
||||
*/
|
||||
|
||||
void*
|
||||
XPT_ArenaCalloc(XPTArena *arena, size_t size, size_t alignment)
|
||||
{
|
||||
if (!size)
|
||||
return NULL;
|
||||
|
||||
if (!arena) {
|
||||
MOZ_ASSERT(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XPTSubArena *subarena;
|
||||
if (alignment == 8) {
|
||||
subarena = &arena->subarena8;
|
||||
} else if (alignment == 1) {
|
||||
subarena = &arena->subarena1;
|
||||
} else {
|
||||
MOZ_ASSERT(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t bytes = ALIGN_RND(size, alignment);
|
||||
|
||||
if (bytes > subarena->space) {
|
||||
BLK_HDR* new_block;
|
||||
size_t block_header_size = ALIGN_RND(sizeof(BLK_HDR), alignment);
|
||||
size_t new_space = subarena->block_size;
|
||||
|
||||
while (bytes > new_space - block_header_size)
|
||||
new_space += subarena->block_size;
|
||||
|
||||
new_block =
|
||||
static_cast<BLK_HDR*>(calloc(new_space / alignment, alignment));
|
||||
if (!new_block) {
|
||||
subarena->next = NULL;
|
||||
subarena->space = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* link block into the list of blocks for use when we destroy */
|
||||
new_block->next = subarena->first;
|
||||
subarena->first = new_block;
|
||||
|
||||
/* set info for current block */
|
||||
subarena->next =
|
||||
reinterpret_cast<uint8_t*>(new_block) + block_header_size;
|
||||
subarena->space = new_space - block_header_size;
|
||||
|
||||
#ifdef DEBUG
|
||||
/* mark block for corruption check */
|
||||
memset(subarena->next, 0xcd, subarena->space);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
/* do corruption check */
|
||||
size_t i;
|
||||
for (i = 0; i < bytes; ++i) {
|
||||
MOZ_ASSERT(subarena->next[i] == 0xcd);
|
||||
}
|
||||
/* we guarantee that the block will be filled with zeros */
|
||||
memset(subarena->next, 0, bytes);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t* p = subarena->next;
|
||||
subarena->next += bytes;
|
||||
subarena->space -= bytes;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static size_t
|
||||
SizeOfSubArenaExcludingThis(XPTSubArena *subarena, MozMallocSizeOf mallocSizeOf)
|
||||
{
|
||||
size_t n = 0;
|
||||
|
||||
BLK_HDR* cur = subarena->first;
|
||||
while (cur) {
|
||||
BLK_HDR* next = cur->next;
|
||||
n += mallocSizeOf(cur);
|
||||
cur = next;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t
|
||||
XPT_SizeOfArenaIncludingThis(XPTArena *arena, MozMallocSizeOf mallocSizeOf)
|
||||
{
|
||||
size_t n = mallocSizeOf(arena);
|
||||
n += SizeOfSubArenaExcludingThis(&arena->subarena8, mallocSizeOf);
|
||||
n += SizeOfSubArenaExcludingThis(&arena->subarena1, mallocSizeOf);
|
||||
return n;
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=8 sts=4 et sw=4 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* Simple arena allocator for xpt (which avoids using NSPR).
|
||||
*/
|
||||
|
||||
#ifndef __xpt_arena_h__
|
||||
#define __xpt_arena_h__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Simple Arena support. Use with caution!
|
||||
*/
|
||||
|
||||
struct XPTArena;
|
||||
|
||||
XPTArena*
|
||||
XPT_NewArena(size_t block_size8, size_t block_size1);
|
||||
|
||||
void
|
||||
XPT_DestroyArena(XPTArena *arena);
|
||||
|
||||
void*
|
||||
XPT_ArenaCalloc(XPTArena *arena, size_t size, size_t alignment);
|
||||
|
||||
size_t
|
||||
XPT_SizeOfArenaIncludingThis(XPTArena *arena, MozMallocSizeOf mallocSizeOf);
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
|
||||
#define XPT_CALLOC8(_arena, _bytes) XPT_ArenaCalloc((_arena), (_bytes), 8)
|
||||
#define XPT_CALLOC1(_arena, _bytes) XPT_ArenaCalloc((_arena), (_bytes), 1)
|
||||
#define XPT_NEWZAP(_arena, _struct) ((_struct *) XPT_CALLOC8((_arena), sizeof(_struct)))
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
|
||||
#endif /* __xpt_arena_h__ */
|
@ -1,243 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* Structures for representing typelib structures in memory.
|
||||
* http://www.mozilla.org/scriptable/typelib_file.html
|
||||
*/
|
||||
|
||||
#ifndef xpt_struct_h
|
||||
#define xpt_struct_h
|
||||
|
||||
#include "nsID.h"
|
||||
#include <stdint.h>
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
struct XPTInterfaceDescriptor;
|
||||
struct XPTConstDescriptor;
|
||||
struct XPTMethodDescriptor;
|
||||
struct XPTParamDescriptor;
|
||||
struct XPTTypeDescriptor;
|
||||
struct XPTTypeDescriptorPrefix;
|
||||
|
||||
struct XPTHeader {
|
||||
static const uint16_t kNumInterfaces;
|
||||
static const XPTInterfaceDescriptor kInterfaces[];
|
||||
static const XPTTypeDescriptor kTypes[];
|
||||
static const XPTParamDescriptor kParams[];
|
||||
static const XPTMethodDescriptor kMethods[];
|
||||
static const XPTConstDescriptor kConsts[];
|
||||
|
||||
// All of the strings for this header, including their null
|
||||
// terminators, concatenated into a single string.
|
||||
static const char kStrings[];
|
||||
};
|
||||
|
||||
/*
|
||||
* An InterfaceDescriptor describes a single XPCOM interface, including all of
|
||||
* its methods.
|
||||
*/
|
||||
struct XPTInterfaceDescriptor {
|
||||
static const uint8_t kScriptableMask = 0x80;
|
||||
static const uint8_t kFunctionMask = 0x40;
|
||||
static const uint8_t kBuiltinClassMask = 0x20;
|
||||
static const uint8_t kMainProcessScriptableOnlyMask = 0x10;
|
||||
|
||||
bool IsScriptable() const { return !!(mFlags & kScriptableMask); }
|
||||
bool IsFunction() const { return !!(mFlags & kFunctionMask); }
|
||||
bool IsBuiltinClass() const { return !!(mFlags & kBuiltinClassMask); }
|
||||
bool IsMainProcessScriptableOnly() const { return !!(mFlags & kMainProcessScriptableOnlyMask); }
|
||||
|
||||
inline const char* Name() const;
|
||||
inline const XPTMethodDescriptor& Method(size_t aIndex) const;
|
||||
inline const XPTConstDescriptor& Const(size_t aIndex) const;
|
||||
|
||||
/*
|
||||
* This field ordering minimizes the size of this struct.
|
||||
*/
|
||||
nsID mIID;
|
||||
uint32_t mName; // Index into XPTHeader::mStrings.
|
||||
uint16_t mMethodDescriptors; // Index into XPTHeader::mMethods.
|
||||
uint16_t mConstDescriptors; // Index into XPTHeader::mConsts.
|
||||
uint16_t mParentInterface;
|
||||
uint16_t mNumMethods;
|
||||
uint16_t mNumConstants;
|
||||
uint8_t mFlags;
|
||||
};
|
||||
|
||||
/*
|
||||
* A TypeDescriptor is a union used to identify the type of a method
|
||||
* argument or return value.
|
||||
*
|
||||
* There are three types of TypeDescriptors:
|
||||
*
|
||||
* SimpleTypeDescriptor
|
||||
* InterfaceTypeDescriptor
|
||||
* InterfaceIsTypeDescriptor
|
||||
*
|
||||
* The tag field in the prefix indicates which of the variant TypeDescriptor
|
||||
* records is being used, and hence which union members are valid. Values from 0
|
||||
* to 17 refer to SimpleTypeDescriptors. The value 18 designates an
|
||||
* InterfaceTypeDescriptor, while 19 represents an InterfaceIsTypeDescriptor.
|
||||
*/
|
||||
|
||||
/* why bother with a struct? - other code relies on this being a struct */
|
||||
struct XPTTypeDescriptorPrefix {
|
||||
uint8_t TagPart() const {
|
||||
static const uint8_t kFlagMask = 0xe0;
|
||||
return (uint8_t) (mFlags & ~kFlagMask);
|
||||
}
|
||||
|
||||
uint8_t mFlags;
|
||||
};
|
||||
|
||||
/*
|
||||
* The following enum maps mnemonic names to the different numeric values
|
||||
* of XPTTypeDescriptor->tag.
|
||||
*/
|
||||
enum XPTTypeDescriptorTags {
|
||||
TD_INT8 = 0,
|
||||
TD_INT16 = 1,
|
||||
TD_INT32 = 2,
|
||||
TD_INT64 = 3,
|
||||
TD_UINT8 = 4,
|
||||
TD_UINT16 = 5,
|
||||
TD_UINT32 = 6,
|
||||
TD_UINT64 = 7,
|
||||
TD_FLOAT = 8,
|
||||
TD_DOUBLE = 9,
|
||||
TD_BOOL = 10,
|
||||
TD_CHAR = 11,
|
||||
TD_WCHAR = 12,
|
||||
TD_VOID = 13,
|
||||
TD_PNSIID = 14,
|
||||
TD_DOMSTRING = 15,
|
||||
TD_PSTRING = 16,
|
||||
TD_PWSTRING = 17,
|
||||
TD_INTERFACE_TYPE = 18,
|
||||
TD_INTERFACE_IS_TYPE = 19,
|
||||
TD_ARRAY = 20,
|
||||
TD_PSTRING_SIZE_IS = 21,
|
||||
TD_PWSTRING_SIZE_IS = 22,
|
||||
TD_UTF8STRING = 23,
|
||||
TD_CSTRING = 24,
|
||||
TD_ASTRING = 25,
|
||||
TD_JSVAL = 26
|
||||
};
|
||||
|
||||
struct XPTTypeDescriptor {
|
||||
uint8_t Tag() const {
|
||||
return mPrefix.TagPart();
|
||||
}
|
||||
|
||||
uint8_t ArgNum() const {
|
||||
MOZ_ASSERT(Tag() == TD_INTERFACE_IS_TYPE ||
|
||||
Tag() == TD_PSTRING_SIZE_IS ||
|
||||
Tag() == TD_PWSTRING_SIZE_IS ||
|
||||
Tag() == TD_ARRAY);
|
||||
return mData1;
|
||||
}
|
||||
|
||||
const XPTTypeDescriptor* ArrayElementType() const {
|
||||
MOZ_ASSERT(Tag() == TD_ARRAY);
|
||||
return &XPTHeader::kTypes[mData2];
|
||||
}
|
||||
|
||||
// We store the 16-bit iface value as two 8-bit values in order to
|
||||
// avoid 16-bit alignment requirements for XPTTypeDescriptor, which
|
||||
// reduces its size and also the size of XPTParamDescriptor.
|
||||
uint16_t InterfaceIndex() const {
|
||||
MOZ_ASSERT(Tag() == TD_INTERFACE_TYPE);
|
||||
return (mData1 << 8) | mData2;
|
||||
}
|
||||
|
||||
XPTTypeDescriptorPrefix mPrefix;
|
||||
|
||||
// The data for the different variants is stored in these two data fields.
|
||||
// These should only be accessed via the getter methods above, which will
|
||||
// assert if the tag is invalid. The memory layout here doesn't exactly match
|
||||
// the on-disk format. This is to save memory. Some fields for some cases are
|
||||
// smaller than they are on disk or omitted entirely.
|
||||
uint8_t mData1;
|
||||
uint8_t mData2;
|
||||
};
|
||||
|
||||
/*
|
||||
* A ConstDescriptor records the name and value of a scoped interface constant.
|
||||
* This is allowed only for a subset of types.
|
||||
*
|
||||
* The type of the value record is determined by the contents of the associated
|
||||
* TypeDescriptor record. For instance, if type corresponds to int16_t, then
|
||||
* value is a 16-bit signed integer.
|
||||
*/
|
||||
union XPTConstValue {
|
||||
int16_t i16;
|
||||
uint16_t ui16;
|
||||
int32_t i32;
|
||||
uint32_t ui32;
|
||||
|
||||
// These constructors are needed to statically initialize different cases of
|
||||
// the union because MSVC does not support the use of designated initializers
|
||||
// in C++ code. They need to be constexpr to ensure that no initialization code
|
||||
// is run at startup, to enable sharing of this memory between Firefox processes.
|
||||
explicit constexpr XPTConstValue(int16_t aInt) : i16(aInt) {}
|
||||
explicit constexpr XPTConstValue(uint16_t aInt) : ui16(aInt) {}
|
||||
explicit constexpr XPTConstValue(int32_t aInt) : i32(aInt) {}
|
||||
explicit constexpr XPTConstValue(uint32_t aInt) : ui32(aInt) {}
|
||||
};
|
||||
|
||||
struct XPTConstDescriptor {
|
||||
const char* Name() const {
|
||||
return &XPTHeader::kStrings[mName];
|
||||
}
|
||||
|
||||
uint32_t mName; // Index into XPTHeader::mStrings.
|
||||
XPTTypeDescriptor mType;
|
||||
XPTConstValue mValue;
|
||||
};
|
||||
|
||||
/*
|
||||
* A ParamDescriptor is used to describe either a single argument to a method or
|
||||
* a method's result.
|
||||
*/
|
||||
struct XPTParamDescriptor {
|
||||
uint8_t mFlags;
|
||||
XPTTypeDescriptor mType;
|
||||
};
|
||||
|
||||
/*
|
||||
* A MethodDescriptor is used to describe a single interface method.
|
||||
*/
|
||||
struct XPTMethodDescriptor {
|
||||
const char* Name() const {
|
||||
return &XPTHeader::kStrings[mName];
|
||||
}
|
||||
const XPTParamDescriptor& Param(uint8_t aIndex) const {
|
||||
return XPTHeader::kParams[mParams + aIndex];
|
||||
}
|
||||
|
||||
uint32_t mName; // Index into XPTHeader::mStrings.
|
||||
uint32_t mParams; // Index into XPTHeader::mParams.
|
||||
uint8_t mFlags;
|
||||
uint8_t mNumArgs;
|
||||
};
|
||||
|
||||
const char*
|
||||
XPTInterfaceDescriptor::Name() const {
|
||||
return &XPTHeader::kStrings[mName];
|
||||
}
|
||||
|
||||
const XPTMethodDescriptor&
|
||||
XPTInterfaceDescriptor::Method(size_t aIndex) const {
|
||||
return XPTHeader::kMethods[mMethodDescriptors + aIndex];
|
||||
}
|
||||
|
||||
const XPTConstDescriptor&
|
||||
XPTInterfaceDescriptor::Const(size_t aIndex) const {
|
||||
return XPTHeader::kConsts[mConstDescriptors + aIndex];
|
||||
}
|
||||
|
||||
#endif /* xpt_struct_h */
|
Loading…
Reference in New Issue
Block a user