Fix for bug 716997 (Allow new DOM bindings with 0 methods or properties). r=jst.

--HG--
extra : rebase_source : 2b16fa38254362cdedc136a8a4b07261ab2f6a76
This commit is contained in:
Peter Van der Beken 2011-10-14 23:21:39 +02:00
parent 0fc6b252db
commit 8f4abab950
3 changed files with 45 additions and 12 deletions

View File

@ -63,6 +63,8 @@ static jsid s_prototype_id = JSID_VOID;
static jsid s_length_id = JSID_VOID;
static jsid s_VOID_id = JSID_VOID;
bool
DefineStaticJSVal(JSContext *cx, jsid &id, const char *string)
{
@ -241,6 +243,20 @@ Unwrap(JSContext *cx, jsval v, NoType **ppArg, nsISupports **ppArgRef, jsval *vp
// properties. If they do we set the value to USE_CACHE again, if they're not we set the value to
// DONT_USE_CACHE. If the value is USE_CACHE we do the fast lookup.
template<class LC>
typename ListBase<LC>::Properties ListBase<LC>::sProtoProperties[] = {
{ s_VOID_id, NULL, NULL }
};
template<class LC>
size_t ListBase<LC>::sProtoPropertiesCount = 0;
template<class LC>
typename ListBase<LC>::Methods ListBase<LC>::sProtoMethods[] = {
{ s_VOID_id, NULL, 0 }
};
template<class LC>
size_t ListBase<LC>::sProtoMethodsCount = 0;
template<class LC>
ListBase<LC> ListBase<LC>::instance;
@ -482,7 +498,7 @@ ListBase<LC>::getPrototype(JSContext *cx, XPCWrappedNativeScope *scope)
if (!interfacePrototype)
return NULL;
for (size_t n = 0; n < ArrayLength(sProtoProperties); ++n) {
for (size_t n = 0; n < sProtoPropertiesCount; ++n) {
JS_ASSERT(sProtoProperties[n].getter);
jsid id = sProtoProperties[n].id;
uintN attrs = JSPROP_ENUMERATE | JSPROP_SHARED;
@ -493,7 +509,7 @@ ListBase<LC>::getPrototype(JSContext *cx, XPCWrappedNativeScope *scope)
return NULL;
}
for (size_t n = 0; n < ArrayLength(sProtoMethods); ++n) {
for (size_t n = 0; n < sProtoMethodsCount; ++n) {
jsid id = sProtoMethods[n].id;
JSFunction *fun = JS_NewFunctionById(cx, sProtoMethods[n].native, sProtoMethods[n].nargs,
0, js::GetObjectParent(interfacePrototype), id);
@ -897,7 +913,7 @@ bool
ListBase<LC>::protoIsClean(JSContext *cx, JSObject *proto, bool *isClean)
{
JSPropertyDescriptor desc;
for (size_t n = 0; n < ArrayLength(sProtoProperties); ++n) {
for (size_t n = 0; n < sProtoPropertiesCount; ++n) {
jsid id = sProtoProperties[n].id;
if (!JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, &desc))
return false;
@ -910,7 +926,7 @@ ListBase<LC>::protoIsClean(JSContext *cx, JSObject *proto, bool *isClean)
}
}
for (size_t n = 0; n < ArrayLength(sProtoMethods); ++n) {
for (size_t n = 0; n < sProtoMethodsCount; ++n) {
jsid id = sProtoMethods[n].id;
if (!JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, &desc))
return false;
@ -951,7 +967,7 @@ ListBase<LC>::resolveNativeName(JSContext *cx, JSObject *proxy, jsid id, JSPrope
{
JS_ASSERT(xpc::WrapperFactory::IsXrayWrapper(proxy));
for (size_t n = 0; n < ArrayLength(sProtoProperties); ++n) {
for (size_t n = 0; n < sProtoPropertiesCount; ++n) {
if (id == sProtoProperties[n].id) {
desc->attrs = JSPROP_ENUMERATE | JSPROP_SHARED;
if (!sProtoProperties[n].setter)
@ -963,7 +979,7 @@ ListBase<LC>::resolveNativeName(JSContext *cx, JSObject *proxy, jsid id, JSPrope
}
}
for (size_t n = 0; n < ArrayLength(sProtoMethods); ++n) {
for (size_t n = 0; n < sProtoMethodsCount; ++n) {
if (id == sProtoMethods[n].id) {
JSFunction *fun = JS_NewFunctionById(cx, sProtoMethods[n].native,
sProtoMethods[n].nargs, 0, proxy, id);
@ -1007,7 +1023,7 @@ ListBase<LC>::nativeGet(JSContext *cx, JSObject *proxy, JSObject *proto, jsid id
#endif
}
for (size_t n = 0; n < ArrayLength(sProtoProperties); ++n) {
for (size_t n = 0; n < sProtoPropertiesCount; ++n) {
if (id == sProtoProperties[n].id) {
*found = true;
if (!vp)
@ -1016,7 +1032,7 @@ ListBase<LC>::nativeGet(JSContext *cx, JSObject *proxy, JSObject *proto, jsid id
return sProtoProperties[n].getter(cx, proxy, id, vp);
}
}
for (size_t n = 0; n < ArrayLength(sProtoMethods); ++n) {
for (size_t n = 0; n < sProtoMethodsCount; ++n) {
if (id == sProtoMethods[n].id) {
*found = true;
if (!vp)

View File

@ -183,7 +183,9 @@ private:
};
static Properties sProtoProperties[];
static size_t sProtoPropertiesCount;
static Methods sProtoMethods[];
static size_t sProtoMethodsCount;
static JSObject *ensureExpandoObject(JSContext *cx, JSObject *obj);

View File

@ -443,7 +443,7 @@ listTemplate = (
" JS_EnumerateStub,\n"
" JS_ResolveStub,\n"
" JS_ConvertStub,\n"
" NULL, /* finalize */\n"
" JS_FinalizeStub,\n"
" NULL, /* reserved0 */\n"
" NULL, /* checkAccess */\n"
" NULL, /* call */\n"
@ -527,16 +527,27 @@ nameSetterTemplate = (
"}\n"
"\n")
listTemplateFooter = (
propertiesTemplate = (
"template<>\n"
"${name}Wrapper::Properties ${name}Wrapper::sProtoProperties[] = {\n"
"${properties}\n"
"};\n"
"\n""template<>\n"
"\n"
"template<>\n"
"size_t ${name}Wrapper::sProtoPropertiesCount = ArrayLength(${name}Wrapper::sProtoProperties);\n"
"\n")
methodsTemplate = (
"template<>\n"
"${name}Wrapper::Methods ${name}Wrapper::sProtoMethods[] = {\n"
"${methods}\n"
"};\n"
"\n"
"template<>\n"
"size_t ${name}Wrapper::sProtoMethodsCount = ArrayLength(${name}Wrapper::sProtoMethods);\n"
"\n")
listTemplateFooter = (
"template class ListBase<${name}Class>;\n"
"\n"
"JSObject*\n"
@ -718,7 +729,11 @@ def writeStubFile(filename, config, interfaces):
else:
propertiesList.append(writeAttrStubs(f, clazz.name, member))
f.write(string.Template(listTemplateFooter).substitute(clazz, methods=",\n".join(methodsList), properties=",\n".join(propertiesList)))
if len(propertiesList) > 0:
f.write(string.Template(propertiesTemplate).substitute(clazz, properties=",\n".join(propertiesList)))
if len(methodsList) > 0:
f.write(string.Template(methodsTemplate).substitute(clazz, methods=",\n".join(methodsList)))
f.write(string.Template(listTemplateFooter).substitute(clazz))
f.write("// Register prototypes\n\n")