mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 822470 part 7. Use new callback codegen for conversion to and from JS. r=peterv
NodeFilter, EventListener, and DOMTransaction will be updated to use the new codegen once we've fixed the consumers.
This commit is contained in:
parent
1ddbf2e612
commit
fd94476421
@ -1169,6 +1169,41 @@ WrapNewBindingObject(JSContext* cx, JSObject* scope, T& value,
|
||||
return WrapNewBindingObjectHelper<T>::Wrap(cx, scope, value, vp);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline JSObject*
|
||||
GetCallbackFromCallbackObject(T* aObj)
|
||||
{
|
||||
return aObj->Callback();
|
||||
}
|
||||
|
||||
// Helper for getting the callback JSObject* of a smart ptr around a
|
||||
// CallbackObject or a reference to a CallbackObject or something like
|
||||
// that.
|
||||
template <class T, bool isSmartPtr=HasgetMember<T>::Value>
|
||||
struct GetCallbackFromCallbackObjectHelper
|
||||
{
|
||||
static inline JSObject* Get(const T& aObj)
|
||||
{
|
||||
return GetCallbackFromCallbackObject(aObj.get());
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct GetCallbackFromCallbackObjectHelper<T, false>
|
||||
{
|
||||
static inline JSObject* Get(T& aObj)
|
||||
{
|
||||
return GetCallbackFromCallbackObject(&aObj);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline JSObject*
|
||||
GetCallbackFromCallbackObject(T& aObj)
|
||||
{
|
||||
return GetCallbackFromCallbackObjectHelper<T>::Get(aObj);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
InternJSString(JSContext* cx, jsid& id, const char* chars)
|
||||
{
|
||||
|
@ -273,6 +273,9 @@ DOMInterfaces = {
|
||||
}],
|
||||
|
||||
'EventListener': [
|
||||
{
|
||||
'nativeType': 'nsIDOMEventListener'
|
||||
},
|
||||
{
|
||||
'workers': True,
|
||||
}],
|
||||
@ -305,6 +308,7 @@ DOMInterfaces = {
|
||||
'DOMTransaction': [
|
||||
{
|
||||
'nativeType': 'nsIUndoManagerTransaction',
|
||||
'headerFile': 'nsIUndoManagerTransaction.h',
|
||||
}],
|
||||
|
||||
'UndoManager': [
|
||||
@ -535,6 +539,11 @@ DOMInterfaces = {
|
||||
'attributes' ]
|
||||
},
|
||||
|
||||
'NodeFilter': {
|
||||
'nativeType': 'nsIDOMNodeFilter',
|
||||
'headerFile': 'nsIDOMNodeFilter.h',
|
||||
},
|
||||
|
||||
'NodeList': {
|
||||
'nativeType': 'nsINodeList',
|
||||
'resultNotAddRefed': [ 'item' ]
|
||||
@ -1039,12 +1048,6 @@ DOMInterfaces = {
|
||||
'wrapperCache': False
|
||||
},
|
||||
|
||||
'TestCallbackInterface': {
|
||||
'nativeType': 'mozilla::dom::TestCallbackInterfaceOld',
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False
|
||||
},
|
||||
|
||||
'IndirectlyImplementedInterface': {
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False,
|
||||
|
@ -2519,6 +2519,34 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
|
||||
descriptor = descriptorProvider.getDescriptor(
|
||||
type.unroll().inner.identifier.name)
|
||||
|
||||
if (descriptor.interface.isCallback() and
|
||||
descriptor.interface.identifier.name != "NodeFilter" and
|
||||
descriptor.interface.identifier.name != "EventListener" and
|
||||
descriptor.interface.identifier.name != "DOMTransaction"):
|
||||
if descriptor.workers:
|
||||
if type.nullable():
|
||||
declType = CGGeneric("JSObject*")
|
||||
else:
|
||||
declType = CGGeneric("NonNull<JSObject>")
|
||||
conversion = " ${declName} = &${val}.toObject();\n"
|
||||
else:
|
||||
name = descriptor.interface.identifier.name
|
||||
if type.nullable():
|
||||
declType = CGGeneric("nsRefPtr<%s>" % name);
|
||||
else:
|
||||
declType = CGGeneric("OwningNonNull<%s>" % name)
|
||||
conversion = (
|
||||
" bool inited;\n"
|
||||
" ${declName} = new %s(cx, ${obj}, &${val}.toObject(), &inited);\n"
|
||||
" if (!inited) {\n"
|
||||
"%s\n"
|
||||
" }\n" % (name, CGIndenter(exceptionCodeIndented).define()))
|
||||
template = wrapObjectTemplate(conversion, type,
|
||||
"${declName} = nullptr",
|
||||
failureCode)
|
||||
return (template, declType, None, isOptional)
|
||||
|
||||
# This is an interface that we implement as a concrete class
|
||||
# or an XPCOM interface.
|
||||
|
||||
@ -3333,7 +3361,11 @@ if (!returnArray) {
|
||||
CGIndenter(exceptionCodeIndented, 4).define())) +
|
||||
setValue("JS::ObjectValue(*returnArray)"), False)
|
||||
|
||||
if type.isGeckoInterface():
|
||||
if (type.isGeckoInterface() and
|
||||
(not type.isCallbackInterface() or
|
||||
type.unroll().inner.identifier.name == "EventListener" or
|
||||
type.unroll().inner.identifier.name == "NodeFilter" or
|
||||
type.unroll().inner.identifier.name == "DOMTransaction")):
|
||||
descriptor = descriptorProvider.getDescriptor(type.unroll().inner.identifier.name)
|
||||
if type.nullable():
|
||||
wrappingCode = ("if (!%s) {\n" % (result) +
|
||||
@ -3400,22 +3432,24 @@ if (!%(resultStr)s) {
|
||||
"exceptionCode" : exceptionCode } +
|
||||
setValue("JS::StringValue(%s_str)" % result), False)
|
||||
|
||||
if type.isCallback():
|
||||
assert not type.isInterface()
|
||||
# XXXbz we're going to assume that callback types are always
|
||||
# nullable and always have [TreatNonCallableAsNull] for now.
|
||||
if type.isCallback() or type.isCallbackInterface():
|
||||
# See comments in WrapNewBindingObject explaining why we need
|
||||
# to wrap here.
|
||||
# NB: setValue(..., True) calls JS_WrapValue(), so is fallible
|
||||
if descriptorProvider.workers:
|
||||
return (setValue("JS::ObjectOrNullValue(%s)" % result, True), False)
|
||||
|
||||
wrapCode = (("if (%(result)s) {\n" +
|
||||
CGIndenter(CGGeneric(setValue(
|
||||
"JS::ObjectValue(*%(result)s->Callable())", True))).define() + "\n"
|
||||
"} else {\n" +
|
||||
CGIndenter(CGGeneric(setValue("JS::NullValue()"))).define() + "\n"
|
||||
"}") % { "result": result })
|
||||
wrapCode = setValue(
|
||||
"JS::ObjectValue(*GetCallbackFromCallbackObject(%(result)s))",
|
||||
True)
|
||||
if type.nullable():
|
||||
wrapCode = (
|
||||
"if (%(result)s) {\n" +
|
||||
CGIndenter(CGGeneric(wrapCode)).define() + "\n"
|
||||
"} else {\n" +
|
||||
CGIndenter(CGGeneric(setValue("JS::NullValue()"))).define() + "\n"
|
||||
"}")
|
||||
wrapCode = wrapCode % { "result": result }
|
||||
return wrapCode, False
|
||||
|
||||
if type.tag() == IDLType.Tags.any:
|
||||
@ -7305,7 +7339,11 @@ class CGNativeMember(ClassMethod):
|
||||
type = type.inner
|
||||
return str(type), True, True
|
||||
|
||||
if type.isGeckoInterface():
|
||||
if (type.isGeckoInterface() and
|
||||
(not type.isCallbackInterface() or
|
||||
type.unroll().inner.identifier.name == "NodeFilter" or
|
||||
type.unroll().inner.identifier.name == "EventListener" or
|
||||
type.unroll().inner.identifier.name == "DOMTransaction")):
|
||||
iface = type.unroll().inner
|
||||
argIsPointer = type.nullable() or iface.isExternal()
|
||||
forceOwningType = iface.isCallback() or isMember
|
||||
@ -7350,18 +7388,23 @@ class CGNativeMember(ClassMethod):
|
||||
if type.isEnum():
|
||||
return type.inner.identifier.name, False, True
|
||||
|
||||
if type.isCallback():
|
||||
if type.isCallback() or type.isCallbackInterface():
|
||||
forceOwningType = optional or isMember
|
||||
if type.nullable():
|
||||
if optional:
|
||||
if forceOwningType:
|
||||
declType = "nsRefPtr<%s>"
|
||||
else:
|
||||
declType = "%s*"
|
||||
else:
|
||||
if optional:
|
||||
if forceOwningType:
|
||||
declType = "OwningNonNull<%s>"
|
||||
else:
|
||||
declType = "%s&"
|
||||
return declType % type.unroll().identifier.name, False, False
|
||||
if type.isCallback():
|
||||
name = type.unroll().identifier.name
|
||||
else:
|
||||
name = type.unroll().inner.identifier.name
|
||||
return declType % name, False, False
|
||||
|
||||
if type.isAny():
|
||||
return "JS::Value", False, False
|
||||
|
@ -3,6 +3,7 @@
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from WebIDL import IDLInterface, IDLExternalInterface
|
||||
import os
|
||||
|
||||
autogenerated_comment = "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n"
|
||||
|
||||
@ -155,11 +156,16 @@ class Descriptor(DescriptorProvider):
|
||||
|
||||
# Read the desc, and fill in the relevant defaults.
|
||||
ifaceName = self.interface.identifier.name
|
||||
if self.interface.isExternal() or self.interface.isCallback():
|
||||
if self.interface.isExternal():
|
||||
if self.workers:
|
||||
nativeTypeDefault = "JSObject"
|
||||
else:
|
||||
nativeTypeDefault = "nsIDOM" + ifaceName
|
||||
elif self.interface.isCallback():
|
||||
if self.workers:
|
||||
nativeTypeDefault = "JSObject"
|
||||
else:
|
||||
nativeTypeDefault = "mozilla::dom::" + ifaceName
|
||||
else:
|
||||
if self.workers:
|
||||
nativeTypeDefault = "mozilla::dom::workers::" + ifaceName
|
||||
@ -172,6 +178,13 @@ class Descriptor(DescriptorProvider):
|
||||
# Do something sane for JSObject
|
||||
if self.nativeType == "JSObject":
|
||||
headerDefault = "jsapi.h"
|
||||
elif self.interface.isCallback():
|
||||
# A copy of CGHeaders.getDeclarationFilename; we can't
|
||||
# import it here, sadly.
|
||||
# Use our local version of the header, not the exported one, so that
|
||||
# test bindings, which don't export, will work correctly.
|
||||
basename = os.path.basename(self.interface.filename())
|
||||
headerDefault = basename.replace('.webidl', 'Binding.h')
|
||||
else:
|
||||
if self.workers:
|
||||
headerDefault = "mozilla/dom/workers/bindings/%s.h" % ifaceName
|
||||
|
@ -82,17 +82,6 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
};
|
||||
|
||||
// IID for the TestCallbackInterface
|
||||
#define NS_TEST_CALLBACK_INTERFACE_IID \
|
||||
{ 0xbf711ba4, 0xc8f6, 0x46cf, \
|
||||
{ 0xba, 0x5b, 0xaa, 0xe2, 0x78, 0x18, 0xe6, 0x4a } }
|
||||
class TestCallbackInterfaceOld : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_TEST_CALLBACK_INTERFACE_IID)
|
||||
NS_DECL_ISUPPORTS
|
||||
};
|
||||
|
||||
class TestNonWrapperCacheInterface : public nsISupports
|
||||
{
|
||||
public:
|
||||
@ -302,20 +291,20 @@ public:
|
||||
void PassOptionalNonNullExternal(const Optional<TestExternalInterface*>&);
|
||||
void PassOptionalExternalWithDefault(TestExternalInterface*);
|
||||
|
||||
already_AddRefed<TestCallbackInterfaceOld> ReceiveCallbackInterface();
|
||||
already_AddRefed<TestCallbackInterfaceOld> ReceiveNullableCallbackInterface();
|
||||
TestCallbackInterfaceOld* ReceiveWeakCallbackInterface();
|
||||
TestCallbackInterfaceOld* ReceiveWeakNullableCallbackInterface();
|
||||
void PassCallbackInterface(TestCallbackInterfaceOld&);
|
||||
void PassCallbackInterface2(OwningNonNull<TestCallbackInterfaceOld>);
|
||||
void PassNullableCallbackInterface(TestCallbackInterfaceOld*);
|
||||
already_AddRefed<TestCallbackInterfaceOld> NonNullCallbackInterface();
|
||||
void SetNonNullCallbackInterface(TestCallbackInterfaceOld&);
|
||||
already_AddRefed<TestCallbackInterfaceOld> GetNullableCallbackInterface();
|
||||
void SetNullableCallbackInterface(TestCallbackInterfaceOld*);
|
||||
void PassOptionalCallbackInterface(const Optional<nsRefPtr<TestCallbackInterfaceOld> >&);
|
||||
void PassOptionalNonNullCallbackInterface(const Optional<OwningNonNull<TestCallbackInterfaceOld> >&);
|
||||
void PassOptionalCallbackInterfaceWithDefault(TestCallbackInterfaceOld*);
|
||||
already_AddRefed<TestCallbackInterface> ReceiveCallbackInterface();
|
||||
already_AddRefed<TestCallbackInterface> ReceiveNullableCallbackInterface();
|
||||
TestCallbackInterface* ReceiveWeakCallbackInterface();
|
||||
TestCallbackInterface* ReceiveWeakNullableCallbackInterface();
|
||||
void PassCallbackInterface(TestCallbackInterface&);
|
||||
void PassCallbackInterface2(OwningNonNull<TestCallbackInterface>);
|
||||
void PassNullableCallbackInterface(TestCallbackInterface*);
|
||||
already_AddRefed<TestCallbackInterface> NonNullCallbackInterface();
|
||||
void SetNonNullCallbackInterface(TestCallbackInterface&);
|
||||
already_AddRefed<TestCallbackInterface> GetNullableCallbackInterface();
|
||||
void SetNullableCallbackInterface(TestCallbackInterface*);
|
||||
void PassOptionalCallbackInterface(const Optional<nsRefPtr<TestCallbackInterface> >&);
|
||||
void PassOptionalNonNullCallbackInterface(const Optional<OwningNonNull<TestCallbackInterface> >&);
|
||||
void PassOptionalCallbackInterfaceWithDefault(TestCallbackInterface*);
|
||||
|
||||
already_AddRefed<IndirectlyImplementedInterface> ReceiveConsequentialInterface();
|
||||
void PassConsequentialInterface(IndirectlyImplementedInterface&);
|
||||
@ -331,9 +320,9 @@ public:
|
||||
void PassOptionalSequenceOfNullableInts(const Optional<Sequence<Nullable<int32_t> > > &);
|
||||
void PassOptionalNullableSequenceOfNullableInts(const Optional<Nullable<Sequence<Nullable<int32_t> > > > &);
|
||||
void ReceiveCastableObjectSequence(nsTArray< nsRefPtr<TestInterface> > &);
|
||||
void ReceiveCallbackObjectSequence(nsTArray< nsRefPtr<TestCallbackInterfaceOld> > &);
|
||||
void ReceiveCallbackObjectSequence(nsTArray< nsRefPtr<TestCallbackInterface> > &);
|
||||
void ReceiveNullableCastableObjectSequence(nsTArray< nsRefPtr<TestInterface> > &);
|
||||
void ReceiveNullableCallbackObjectSequence(nsTArray< nsRefPtr<TestCallbackInterfaceOld> > &);
|
||||
void ReceiveNullableCallbackObjectSequence(nsTArray< nsRefPtr<TestCallbackInterface> > &);
|
||||
void ReceiveCastableObjectNullableSequence(Nullable< nsTArray< nsRefPtr<TestInterface> > >&);
|
||||
void ReceiveNullableCastableObjectNullableSequence(Nullable< nsTArray< nsRefPtr<TestInterface> > >&);
|
||||
void ReceiveWeakCastableObjectSequence(nsTArray<TestInterface*> &);
|
||||
|
Loading…
Reference in New Issue
Block a user