зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1097267 - Change the enumerate hook usage in XPC and browser. r=bholley
This commit is contained in:
Родитель
d7ef4e6227
Коммит
9dfe5c2fd4
|
@ -1003,9 +1003,9 @@ nsDOMClassInfo::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMClassInfo::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
|
||||
JSContext *cx, JSObject *obj, uint32_t enum_op,
|
||||
jsval *statep, jsid *idp, bool *_retval)
|
||||
nsDOMClassInfo::NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, JS::AutoIdVector &properties,
|
||||
bool *_retval)
|
||||
{
|
||||
NS_WARNING("nsDOMClassInfo::NewEnumerate Don't call me!");
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ interface nsIXPConnectWrappedNative;
|
|||
[ptr] native JSValPtr(JS::Value);
|
||||
[ptr] native JSFreeOpPtr(JSFreeOp);
|
||||
[ref] native JSCallArgsRef(const JS::CallArgs);
|
||||
[ref] native JSAutoIdVector(JS::AutoIdVector);
|
||||
|
||||
/**
|
||||
* Note: This is not really an XPCOM interface. For example, callers must
|
||||
|
@ -113,7 +114,7 @@ interface nsIXPCScriptable : nsISupports
|
|||
|
||||
boolean newEnumerate(in nsIXPConnectWrappedNative wrapper,
|
||||
in JSContextPtr cx, in JSObjectPtr obj,
|
||||
in uint32_t enum_op, in JSValPtr statep, out jsid idp);
|
||||
in JSAutoIdVector properties);
|
||||
|
||||
boolean resolve(in nsIXPConnectWrappedNative wrapper,
|
||||
in JSContextPtr cx, in JSObjectPtr obj, in jsid id,
|
||||
|
|
|
@ -124,7 +124,7 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::SetProperty(nsIXPConnectWrappedNative *wrapper,
|
|||
#endif
|
||||
|
||||
#ifndef XPC_MAP_WANT_NEWENUMERATE
|
||||
NS_IMETHODIMP XPC_MAP_CLASSNAME::NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, uint32_t enum_op, JS::Value * statep, jsid * idp, bool *_retval)
|
||||
NS_IMETHODIMP XPC_MAP_CLASSNAME::NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, JS::AutoIdVector &properties, bool *_retval)
|
||||
{NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -239,55 +239,49 @@ NS_IMPL_RELEASE(nsXPCComponents_Interfaces)
|
|||
#include "xpc_map_end.h" /* This will #undef the above */
|
||||
|
||||
|
||||
/* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t enum_op, in JSValPtr statep, out JSID idp); */
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Interfaces::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
|
||||
JSContext * cx, JSObject * obj,
|
||||
uint32_t enum_op, jsval * statep,
|
||||
jsid * idp, bool *_retval)
|
||||
JSContext *cx, JSObject *obj,
|
||||
JS::AutoIdVector &properties,
|
||||
bool *_retval)
|
||||
{
|
||||
switch (enum_op) {
|
||||
case JSENUMERATE_INIT:
|
||||
case JSENUMERATE_INIT_ALL:
|
||||
{
|
||||
// Lazily init the list of interfaces when someone tries to
|
||||
// enumerate them.
|
||||
if (mInterfaces.IsEmpty()) {
|
||||
XPTInterfaceInfoManager::GetSingleton()->
|
||||
GetScriptableInterfaces(mInterfaces);
|
||||
}
|
||||
|
||||
*statep = JSVAL_ZERO;
|
||||
if (idp)
|
||||
*idp = INT_TO_JSID(mInterfaces.Length());
|
||||
return NS_OK;
|
||||
}
|
||||
case JSENUMERATE_NEXT:
|
||||
{
|
||||
uint32_t idx = statep->toInt32();
|
||||
nsIInterfaceInfo* interface = mInterfaces.SafeElementAt(idx);
|
||||
*statep = UINT_TO_JSVAL(idx + 1);
|
||||
|
||||
if (interface) {
|
||||
const char* name;
|
||||
|
||||
RootedId id(cx);
|
||||
if (NS_SUCCEEDED(interface->GetNameShared(&name)) && name) {
|
||||
RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
|
||||
if (idstr && JS_StringToId(cx, idstr, &id)) {
|
||||
*idp = id;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
}
|
||||
|
||||
case JSENUMERATE_DESTROY:
|
||||
default:
|
||||
*statep = JSVAL_NULL;
|
||||
return NS_OK;
|
||||
// Lazily init the list of interfaces when someone tries to
|
||||
// enumerate them.
|
||||
if (mInterfaces.IsEmpty()) {
|
||||
XPTInterfaceInfoManager::GetSingleton()->
|
||||
GetScriptableInterfaces(mInterfaces);
|
||||
}
|
||||
|
||||
if (!properties.reserve(mInterfaces.Length())) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
for (uint32_t index = 0; index < mInterfaces.Length(); index++) {
|
||||
nsIInterfaceInfo* interface = mInterfaces.SafeElementAt(index);
|
||||
if (!interface)
|
||||
continue;
|
||||
|
||||
const char* name;
|
||||
if (NS_SUCCEEDED(interface->GetNameShared(&name)) && name) {
|
||||
RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
|
||||
if (!idstr) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RootedId id(cx);
|
||||
if (!JS_StringToId(cx, idstr, &id)) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
properties.infallibleAppend(id);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -487,56 +481,49 @@ NS_IMPL_RELEASE(nsXPCComponents_InterfacesByID)
|
|||
#define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
|
||||
#include "xpc_map_end.h" /* This will #undef the above */
|
||||
|
||||
/* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t enum_op, in JSValPtr statep, out JSID idp); */
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_InterfacesByID::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
|
||||
JSContext * cx, JSObject * obj,
|
||||
uint32_t enum_op, jsval * statep,
|
||||
jsid * idp, bool *_retval)
|
||||
JSContext *cx, JSObject *obj,
|
||||
JS::AutoIdVector &properties,
|
||||
bool *_retval)
|
||||
{
|
||||
switch (enum_op) {
|
||||
case JSENUMERATE_INIT:
|
||||
case JSENUMERATE_INIT_ALL:
|
||||
{
|
||||
// Lazily init the list of interfaces when someone tries to
|
||||
// enumerate them.
|
||||
if (mInterfaces.IsEmpty()) {
|
||||
XPTInterfaceInfoManager::GetSingleton()->
|
||||
GetScriptableInterfaces(mInterfaces);
|
||||
}
|
||||
|
||||
*statep = JSVAL_ZERO;
|
||||
if (idp)
|
||||
*idp = INT_TO_JSID(mInterfaces.Length());
|
||||
return NS_OK;
|
||||
}
|
||||
case JSENUMERATE_NEXT:
|
||||
{
|
||||
uint32_t idx = statep->toInt32();
|
||||
nsIInterfaceInfo* interface = mInterfaces.SafeElementAt(idx);
|
||||
*statep = UINT_TO_JSVAL(idx + 1);
|
||||
if (interface) {
|
||||
nsIID const *iid;
|
||||
char idstr[NSID_LENGTH];
|
||||
|
||||
if (NS_SUCCEEDED(interface->GetIIDShared(&iid))) {
|
||||
iid->ToProvidedString(idstr);
|
||||
RootedString jsstr(cx, JS_NewStringCopyZ(cx, idstr));
|
||||
RootedId id(cx);
|
||||
if (jsstr && JS_StringToId(cx, jsstr, &id)) {
|
||||
*idp = id;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
// FALL THROUGH
|
||||
}
|
||||
|
||||
case JSENUMERATE_DESTROY:
|
||||
default:
|
||||
*statep = JSVAL_NULL;
|
||||
return NS_OK;
|
||||
if (mInterfaces.IsEmpty()) {
|
||||
XPTInterfaceInfoManager::GetSingleton()->
|
||||
GetScriptableInterfaces(mInterfaces);
|
||||
}
|
||||
|
||||
if (!properties.reserve(mInterfaces.Length())) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
for (uint32_t index = 0; index < mInterfaces.Length(); index++) {
|
||||
nsIInterfaceInfo* interface = mInterfaces.SafeElementAt(index);
|
||||
if (!interface)
|
||||
continue;
|
||||
|
||||
nsIID const *iid;
|
||||
if (NS_SUCCEEDED(interface->GetIIDShared(&iid))) {
|
||||
char idstr[NSID_LENGTH];
|
||||
iid->ToProvidedString(idstr);
|
||||
RootedString jsstr(cx, JS_NewStringCopyZ(cx, idstr));
|
||||
if (!jsstr) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RootedId id(cx);
|
||||
if (!JS_StringToId(cx, jsstr, &id)) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
properties.infallibleAppend(id);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -738,63 +725,50 @@ NS_IMPL_RELEASE(nsXPCComponents_Classes)
|
|||
#define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
|
||||
#include "xpc_map_end.h" /* This will #undef the above */
|
||||
|
||||
|
||||
/* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t enum_op, in JSValPtr statep, out JSID idp); */
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Classes::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
|
||||
JSContext * cx, JSObject * obj,
|
||||
uint32_t enum_op, jsval * statep,
|
||||
jsid * idp, bool *_retval)
|
||||
JSContext *cx, JSObject *obj,
|
||||
JS::AutoIdVector &properties,
|
||||
bool *_retval)
|
||||
{
|
||||
nsISimpleEnumerator* e;
|
||||
nsCOMPtr<nsIComponentRegistrar> compMgr;
|
||||
if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
switch (enum_op) {
|
||||
case JSENUMERATE_INIT:
|
||||
case JSENUMERATE_INIT_ALL:
|
||||
{
|
||||
nsCOMPtr<nsIComponentRegistrar> compMgr;
|
||||
if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr ||
|
||||
NS_FAILED(compMgr->EnumerateContractIDs(&e)) || !e ) {
|
||||
*statep = JSVAL_NULL;
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
nsCOMPtr<nsISimpleEnumerator> e;
|
||||
if (NS_FAILED(compMgr->EnumerateContractIDs(getter_AddRefs(e))) || !e)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
bool hasMore;
|
||||
nsCOMPtr<nsISupports> isup;
|
||||
while(NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore &&
|
||||
NS_SUCCEEDED(e->GetNext(getter_AddRefs(isup))) && isup) {
|
||||
nsCOMPtr<nsISupportsCString> holder(do_QueryInterface(isup));
|
||||
if (!holder)
|
||||
continue;
|
||||
|
||||
nsAutoCString name;
|
||||
if (NS_SUCCEEDED(holder->GetData(name))) {
|
||||
RootedString idstr(cx, JS_NewStringCopyN(cx, name.get(), name.Length()));
|
||||
if (!idstr) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*statep = PRIVATE_TO_JSVAL(e);
|
||||
if (idp)
|
||||
*idp = INT_TO_JSID(0); // indicate that we don't know the count
|
||||
return NS_OK;
|
||||
}
|
||||
case JSENUMERATE_NEXT:
|
||||
{
|
||||
nsCOMPtr<nsISupports> isup;
|
||||
bool hasMore;
|
||||
e = (nsISimpleEnumerator*) statep->toPrivate();
|
||||
|
||||
if (NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore &&
|
||||
NS_SUCCEEDED(e->GetNext(getter_AddRefs(isup))) && isup) {
|
||||
nsCOMPtr<nsISupportsCString> holder(do_QueryInterface(isup));
|
||||
if (holder) {
|
||||
nsAutoCString name;
|
||||
if (NS_SUCCEEDED(holder->GetData(name))) {
|
||||
RootedString idstr(cx, JS_NewStringCopyN(cx, name.get(), name.Length()));
|
||||
RootedId id(cx);
|
||||
if (idstr && JS_StringToId(cx, idstr, &id)) {
|
||||
*idp = id;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
RootedId id(cx);
|
||||
if (!JS_StringToId(cx, idstr, &id)) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
// else... FALL THROUGH
|
||||
}
|
||||
|
||||
case JSENUMERATE_DESTROY:
|
||||
default:
|
||||
e = (nsISimpleEnumerator*) statep->toPrivate();
|
||||
NS_IF_RELEASE(e);
|
||||
*statep = JSVAL_NULL;
|
||||
return NS_OK;
|
||||
if (!properties.append(id)) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -977,63 +951,51 @@ NS_IMPL_RELEASE(nsXPCComponents_ClassesByID)
|
|||
#define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
|
||||
#include "xpc_map_end.h" /* This will #undef the above */
|
||||
|
||||
/* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t enum_op, in JSValPtr statep, out JSID idp); */
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_ClassesByID::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
|
||||
JSContext * cx, JSObject * obj,
|
||||
uint32_t enum_op, jsval * statep,
|
||||
jsid * idp, bool *_retval)
|
||||
JSContext *cx, JSObject *obj,
|
||||
JS::AutoIdVector &properties,
|
||||
bool *_retval)
|
||||
{
|
||||
|
||||
nsCOMPtr<nsIComponentRegistrar> compMgr;
|
||||
if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
nsISimpleEnumerator* e;
|
||||
if (NS_FAILED(compMgr->EnumerateCIDs(&e)) || !e)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
switch (enum_op) {
|
||||
case JSENUMERATE_INIT:
|
||||
case JSENUMERATE_INIT_ALL:
|
||||
{
|
||||
nsCOMPtr<nsIComponentRegistrar> compMgr;
|
||||
if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr ||
|
||||
NS_FAILED(compMgr->EnumerateCIDs(&e)) || !e ) {
|
||||
*statep = JSVAL_NULL;
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
bool hasMore;
|
||||
nsCOMPtr<nsISupports> isup;
|
||||
while(NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore &&
|
||||
NS_SUCCEEDED(e->GetNext(getter_AddRefs(isup))) && isup) {
|
||||
nsCOMPtr<nsISupportsID> holder(do_QueryInterface(isup));
|
||||
if (!holder)
|
||||
continue;
|
||||
|
||||
char* name;
|
||||
if (NS_SUCCEEDED(holder->ToString(&name)) && name) {
|
||||
RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
|
||||
if (!idstr) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*statep = PRIVATE_TO_JSVAL(e);
|
||||
if (idp)
|
||||
*idp = INT_TO_JSID(0); // indicate that we don't know the count
|
||||
return NS_OK;
|
||||
}
|
||||
case JSENUMERATE_NEXT:
|
||||
{
|
||||
nsCOMPtr<nsISupports> isup;
|
||||
bool hasMore;
|
||||
e = (nsISimpleEnumerator*) statep->toPrivate();
|
||||
|
||||
if (NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore &&
|
||||
NS_SUCCEEDED(e->GetNext(getter_AddRefs(isup))) && isup) {
|
||||
nsCOMPtr<nsISupportsID> holder(do_QueryInterface(isup));
|
||||
if (holder) {
|
||||
char* name;
|
||||
if (NS_SUCCEEDED(holder->ToString(&name)) && name) {
|
||||
RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
|
||||
nsMemory::Free(name);
|
||||
RootedId id(cx);
|
||||
if (idstr && JS_StringToId(cx, idstr, &id)) {
|
||||
*idp = id;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
RootedId id(cx);
|
||||
if (!JS_StringToId(cx, idstr, &id)) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
// else... FALL THROUGH
|
||||
}
|
||||
|
||||
case JSENUMERATE_DESTROY:
|
||||
default:
|
||||
e = (nsISimpleEnumerator*) statep->toPrivate();
|
||||
NS_IF_RELEASE(e);
|
||||
*statep = JSVAL_NULL;
|
||||
return NS_OK;
|
||||
if (!properties.append(id)) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -1240,49 +1202,34 @@ NS_IMPL_RELEASE(nsXPCComponents_Results)
|
|||
#define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
|
||||
#include "xpc_map_end.h" /* This will #undef the above */
|
||||
|
||||
/* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t enum_op, in JSValPtr statep, out JSID idp); */
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Results::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
|
||||
JSContext * cx, JSObject * obj,
|
||||
uint32_t enum_op, jsval * statep,
|
||||
jsid * idp, bool *_retval)
|
||||
JSContext *cx, JSObject *obj,
|
||||
JS::AutoIdVector &properties,
|
||||
bool *_retval)
|
||||
{
|
||||
const void** iter;
|
||||
|
||||
switch (enum_op) {
|
||||
case JSENUMERATE_INIT:
|
||||
case JSENUMERATE_INIT_ALL:
|
||||
{
|
||||
if (idp)
|
||||
*idp = INT_TO_JSID(nsXPCException::GetNSResultCount());
|
||||
|
||||
void** space = (void**) new char[sizeof(void*)];
|
||||
*space = nullptr;
|
||||
*statep = PRIVATE_TO_JSVAL(space);
|
||||
const char* name;
|
||||
const void* iter = nullptr;
|
||||
while (nsXPCException::IterateNSResults(nullptr, &name, nullptr, &iter)) {
|
||||
RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
|
||||
if (!idstr) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
case JSENUMERATE_NEXT:
|
||||
{
|
||||
const char* name;
|
||||
iter = (const void**) statep->toPrivate();
|
||||
if (nsXPCException::IterateNSResults(nullptr, &name, nullptr, iter)) {
|
||||
RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
|
||||
JS::RootedId id(cx);
|
||||
if (idstr && JS_StringToId(cx, idstr, &id)) {
|
||||
*idp = id;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
// else... FALL THROUGH
|
||||
|
||||
RootedId id(cx);
|
||||
if (!JS_StringToId(cx, idstr, &id)) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
case JSENUMERATE_DESTROY:
|
||||
default:
|
||||
iter = (const void**) statep->toPrivate();
|
||||
delete [] (char*) iter;
|
||||
*statep = JSVAL_NULL;
|
||||
if (!properties.append(id)) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -698,7 +698,7 @@ const XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = {
|
|||
nullptr, // deleteGeneric
|
||||
nullptr, nullptr, // watch/unwatch
|
||||
nullptr, // getElements
|
||||
XPC_WN_JSOp_Enumerate,
|
||||
nullptr, // enumerate
|
||||
XPC_WN_JSOp_ThisObject,
|
||||
}
|
||||
}
|
||||
|
@ -928,118 +928,48 @@ XPC_WN_Helper_Resolve(JSContext *cx, HandleObject obj, HandleId id, bool *resolv
|
|||
return retval;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
Here are the enumerator cases:
|
||||
|
||||
set jsclass enumerate to stub (unless noted otherwise)
|
||||
|
||||
if ( helper wants new enumerate )
|
||||
if ( DONT_ENUM_STATICS )
|
||||
forward to scriptable enumerate
|
||||
else
|
||||
if ( set not mutated )
|
||||
forward to scriptable enumerate
|
||||
else
|
||||
call shared enumerate
|
||||
forward to scriptable enumerate
|
||||
else if ( helper wants old enumerate )
|
||||
use this JSOp
|
||||
if ( DONT_ENUM_STATICS )
|
||||
call scriptable enumerate
|
||||
call stub
|
||||
else
|
||||
if ( set not mutated )
|
||||
call scriptable enumerate
|
||||
call stub
|
||||
else
|
||||
call shared enumerate
|
||||
call scriptable enumerate
|
||||
call stub
|
||||
|
||||
else //... if ( helper wants NO enumerate )
|
||||
if ( DONT_ENUM_STATICS )
|
||||
use enumerate stub - don't use this JSOp thing at all
|
||||
else
|
||||
do shared enumerate - don't use this JSOp thing at all
|
||||
*/
|
||||
|
||||
bool
|
||||
XPC_WN_JSOp_Enumerate(JSContext *cx, HandleObject obj, JSIterateOp enum_op,
|
||||
MutableHandleValue statep, MutableHandleId idp)
|
||||
static bool
|
||||
XPC_WN_Helper_Enumerate(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
const js::Class *clazz = js::GetObjectClass(obj);
|
||||
if (!IS_WN_CLASS(clazz) || clazz == &XPC_WN_NoHelper_JSClass.base) {
|
||||
// obj must be a prototype object or a wrapper w/o a
|
||||
// helper. Short circuit this call to the default
|
||||
// implementation.
|
||||
|
||||
return JS_EnumerateState(cx, obj, enum_op, statep, idp);
|
||||
}
|
||||
|
||||
XPCCallContext ccx(JS_CALLER, cx, obj);
|
||||
XPCWrappedNative* wrapper = ccx.GetWrapper();
|
||||
THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper);
|
||||
|
||||
XPCNativeScriptableInfo* si = wrapper->GetScriptableInfo();
|
||||
if (!si)
|
||||
if (!si || !si->GetFlags().WantEnumerate())
|
||||
return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx);
|
||||
|
||||
if (!XPC_WN_Shared_Enumerate(cx, obj))
|
||||
return false;
|
||||
|
||||
bool retval = true;
|
||||
nsresult rv;
|
||||
nsresult rv = si->GetCallback()->Enumerate(wrapper, cx, obj, &retval);
|
||||
if (NS_FAILED(rv))
|
||||
return Throw(rv, cx);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (si->GetFlags().WantNewEnumerate()) {
|
||||
// XXXevilpie I am like 80% sure that has no effect on what is actually
|
||||
// enumerated.
|
||||
// The loop in jsiter.cpp will only put stuff that is actually in idp
|
||||
// into the property id array.
|
||||
if (enum_op == JSENUMERATE_INIT || enum_op == JSENUMERATE_INIT_ALL) {
|
||||
if (wrapper->HasMutatedSet() &&
|
||||
!XPC_WN_Shared_Enumerate(cx, obj)) {
|
||||
statep.set(JSVAL_NULL);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/***************************************************************************/
|
||||
|
||||
rv = si->GetCallback()->
|
||||
NewEnumerate(wrapper, cx, obj, enum_op, statep.address(), idp.address(), &retval);
|
||||
static bool
|
||||
XPC_WN_JSOp_Enumerate(JSContext *cx, HandleObject obj, AutoIdVector &properties)
|
||||
{
|
||||
XPCCallContext ccx(JS_CALLER, cx, obj);
|
||||
XPCWrappedNative* wrapper = ccx.GetWrapper();
|
||||
THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper);
|
||||
|
||||
if ((enum_op == JSENUMERATE_INIT || enum_op == JSENUMERATE_INIT_ALL) &&
|
||||
(NS_FAILED(rv) || !retval)) {
|
||||
statep.set(JSVAL_NULL);
|
||||
}
|
||||
XPCNativeScriptableInfo* si = wrapper->GetScriptableInfo();
|
||||
if (!si || !si->GetFlags().WantNewEnumerate())
|
||||
return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return Throw(rv, cx);
|
||||
return retval;
|
||||
}
|
||||
if (!XPC_WN_Shared_Enumerate(cx, obj))
|
||||
return false;
|
||||
|
||||
if (si->GetFlags().WantEnumerate()) {
|
||||
if (enum_op == JSENUMERATE_INIT || enum_op == JSENUMERATE_INIT_ALL) {
|
||||
if (wrapper->HasMutatedSet() &&
|
||||
!XPC_WN_Shared_Enumerate(cx, obj)) {
|
||||
statep.set(JSVAL_NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
rv = si->GetCallback()->
|
||||
Enumerate(wrapper, cx, obj, &retval);
|
||||
|
||||
if (NS_FAILED(rv) || !retval)
|
||||
statep.set(JSVAL_NULL);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return Throw(rv, cx);
|
||||
if (!retval)
|
||||
return false;
|
||||
// Then fall through and call the default implementation...
|
||||
}
|
||||
}
|
||||
|
||||
// else call js_ObjectOps.enumerate...
|
||||
|
||||
return JS_EnumerateState(cx, obj, enum_op, statep, idp);
|
||||
bool retval = true;
|
||||
nsresult rv = si->GetCallback()->NewEnumerate(wrapper, cx, obj, properties, &retval);
|
||||
if (NS_FAILED(rv))
|
||||
return Throw(rv, cx);
|
||||
return retval;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
|
@ -1131,10 +1061,14 @@ XPCNativeScriptableShared::PopulateJSClass()
|
|||
setProperty = XPC_WN_CannotModifyStrictPropertyStub;
|
||||
mJSClass.base.setProperty = setProperty;
|
||||
|
||||
// We figure out most of the enumerate strategy at call time.
|
||||
MOZ_ASSERT_IF(mFlags.WantEnumerate(), !mFlags.WantNewEnumerate());
|
||||
MOZ_ASSERT_IF(mFlags.WantNewEnumerate(), !mFlags.WantEnumerate());
|
||||
|
||||
if (mFlags.WantNewEnumerate() || mFlags.WantEnumerate())
|
||||
// We will use ops->enumerate set below for NewEnumerate
|
||||
if (mFlags.WantNewEnumerate())
|
||||
mJSClass.base.enumerate = nullptr;
|
||||
else if (mFlags.WantEnumerate())
|
||||
mJSClass.base.enumerate = XPC_WN_Helper_Enumerate;
|
||||
else
|
||||
mJSClass.base.enumerate = XPC_WN_Shared_Enumerate;
|
||||
|
||||
|
@ -1152,7 +1086,8 @@ XPCNativeScriptableShared::PopulateJSClass()
|
|||
mJSClass.base.finalize = XPC_WN_NoHelper_Finalize;
|
||||
|
||||
js::ObjectOps *ops = &mJSClass.base.ops;
|
||||
ops->enumerate = XPC_WN_JSOp_Enumerate;
|
||||
if (mFlags.WantNewEnumerate())
|
||||
ops->enumerate = XPC_WN_JSOp_Enumerate;
|
||||
ops->thisObject = XPC_WN_JSOp_ThisObject;
|
||||
|
||||
|
||||
|
|
|
@ -948,10 +948,6 @@ XPC_WN_CallMethod(JSContext *cx, unsigned argc, jsval *vp);
|
|||
extern bool
|
||||
XPC_WN_GetterSetter(JSContext *cx, unsigned argc, jsval *vp);
|
||||
|
||||
extern bool
|
||||
XPC_WN_JSOp_Enumerate(JSContext *cx, JS::HandleObject obj, JSIterateOp enum_op,
|
||||
JS::MutableHandleValue statep, JS::MutableHandleId idp);
|
||||
|
||||
extern JSObject*
|
||||
XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj);
|
||||
|
||||
|
@ -975,7 +971,7 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj);
|
|||
nullptr, /* deleteGeneric */ \
|
||||
nullptr, nullptr, /* watch/unwatch */ \
|
||||
nullptr, /* getElements */ \
|
||||
XPC_WN_JSOp_Enumerate, \
|
||||
nullptr, /* enumerate */ \
|
||||
XPC_WN_JSOp_ThisObject, \
|
||||
}
|
||||
|
||||
|
@ -998,7 +994,7 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj);
|
|||
nullptr, /* deleteGeneric */ \
|
||||
nullptr, nullptr, /* watch/unwatch */ \
|
||||
nullptr, /* getElements */ \
|
||||
XPC_WN_JSOp_Enumerate, \
|
||||
nullptr, /* enumerate */ \
|
||||
XPC_WN_JSOp_ThisObject, \
|
||||
}
|
||||
|
||||
|
|
|
@ -89,67 +89,36 @@ NS_IMETHODIMP
|
|||
StatementParams::NewEnumerate(nsIXPConnectWrappedNative *aWrapper,
|
||||
JSContext *aCtx,
|
||||
JSObject *aScopeObj,
|
||||
uint32_t aEnumOp,
|
||||
jsval *_statep,
|
||||
jsid *_idp,
|
||||
JS::AutoIdVector &aProperties,
|
||||
bool *_retval)
|
||||
{
|
||||
NS_ENSURE_TRUE(mStatement, NS_ERROR_NOT_INITIALIZED);
|
||||
JS::RootedObject scope(aCtx, aScopeObj);
|
||||
|
||||
switch (aEnumOp) {
|
||||
case JSENUMERATE_INIT:
|
||||
case JSENUMERATE_INIT_ALL:
|
||||
{
|
||||
// Start our internal index at zero.
|
||||
*_statep = JSVAL_ZERO;
|
||||
if (!aProperties.reserve(mParamCount)) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// And set our length, if needed.
|
||||
if (_idp)
|
||||
*_idp = INT_TO_JSID(mParamCount);
|
||||
for (uint32_t i = 0; i < mParamCount; i++) {
|
||||
// Get the name of our parameter.
|
||||
nsAutoCString name;
|
||||
nsresult rv = mStatement->GetParameterName(i, name);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
break;
|
||||
// But drop the first character, which is going to be a ':'.
|
||||
JS::RootedString jsname(aCtx, ::JS_NewStringCopyN(aCtx, &(name.get()[1]),
|
||||
name.Length() - 1));
|
||||
NS_ENSURE_TRUE(jsname, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// Set our name.
|
||||
JS::Rooted<jsid> id(aCtx);
|
||||
if (!::JS_StringToId(aCtx, jsname, &id)) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
case JSENUMERATE_NEXT:
|
||||
{
|
||||
NS_ASSERTION(*_statep != JSVAL_NULL, "Internal state is null!");
|
||||
|
||||
// Make sure we are in range first.
|
||||
uint32_t index = static_cast<uint32_t>(_statep->toInt32());
|
||||
if (index >= mParamCount) {
|
||||
*_statep = JSVAL_NULL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get the name of our parameter.
|
||||
nsAutoCString name;
|
||||
nsresult rv = mStatement->GetParameterName(index, name);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// But drop the first character, which is going to be a ':'.
|
||||
JS::RootedString jsname(aCtx, ::JS_NewStringCopyN(aCtx, &(name.get()[1]),
|
||||
name.Length() - 1));
|
||||
NS_ENSURE_TRUE(jsname, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// Set our name.
|
||||
JS::Rooted<jsid> id(aCtx);
|
||||
if (!::JS_StringToId(aCtx, jsname, &id)) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
*_idp = id;
|
||||
|
||||
// And increment our index.
|
||||
*_statep = INT_TO_JSVAL(++index);
|
||||
|
||||
break;
|
||||
}
|
||||
case JSENUMERATE_DESTROY:
|
||||
{
|
||||
// Clear our state.
|
||||
*_statep = JSVAL_NULL;
|
||||
|
||||
break;
|
||||
}
|
||||
aProperties.infallibleAppend(id);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -21,8 +21,11 @@ function test_params_enumerate()
|
|||
// Make sure they are right.
|
||||
let expected = ["a", "b", "c"];
|
||||
let index = 0;
|
||||
for (let name in stmt.params)
|
||||
for (let name in stmt.params) {
|
||||
if (name == "QueryInterface")
|
||||
continue;
|
||||
do_check_eq(name, expected[index++]);
|
||||
}
|
||||
}
|
||||
|
||||
function test_params_prototype()
|
||||
|
|
Загрузка…
Ссылка в новой задаче