unfinished array support. fixes for exceptions
git-svn-id: svn://10.0.0.236/trunk@46935 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "xpcexception.idl"
|
||||
#include "nsIComponentManager.idl"
|
||||
|
||||
[scriptable, uuid(4b62a640-d26c-11d2-9842-006008962422)]
|
||||
interface nsIXPCInterfaces : nsISupports
|
||||
@@ -47,6 +48,7 @@ interface nsIXPCComponents : nsISupports
|
||||
readonly attribute nsIXPCClassesByID classesByID;
|
||||
readonly attribute nsIJSStackFrameLocation stack;
|
||||
readonly attribute nsIXPCResults results;
|
||||
readonly attribute nsIComponentManager manager;
|
||||
|
||||
/* 'lastResult' is accessable via JavaScript only */
|
||||
/* 'returnCode' is accessable via JavaScript only */
|
||||
|
||||
@@ -38,7 +38,6 @@ interface nsITestXPCFoo : nsISupports {
|
||||
interface nsITestXPCFoo2 : nsITestXPCFoo {
|
||||
};
|
||||
|
||||
|
||||
[scriptable, uuid(CD2F2F40-C5D9-11d2-9838-006008962422)]
|
||||
interface nsIEcho : nsISupports {
|
||||
|
||||
@@ -101,6 +100,9 @@ interface nsIEcho : nsISupports {
|
||||
void SetReceiverReturnOldReceiver(inout nsIEcho aReceiver);
|
||||
|
||||
void MethodWithForwardDeclaredParam(in nsITestXPCSomeUselessThing sut);
|
||||
|
||||
void PseudoQueryInterface(in nsIIDRef uuid,
|
||||
[iid_is(uuid),retval] out nsQIResult result);
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
@@ -141,3 +143,20 @@ interface nsIXPCTestOverloaded : nsISupports {
|
||||
void Foo1(in PRInt32 p1);
|
||||
void Foo2(in PRInt32 p1, in PRInt32 p2);
|
||||
};
|
||||
|
||||
[scriptable, uuid(3d2e64b0-6552-11d3-989e-006008962422)]
|
||||
interface nsIXPCTestArray : nsISupports {
|
||||
void PrintIntegerArray(in PRUint32 count,
|
||||
[array, size_is(count)] in PRInt32 valueArray);
|
||||
void PrintStringArray(in PRUint32 count,
|
||||
[array, size_is(count)] in string valueArray);
|
||||
void MultiplyEachItemInIntegerArray(
|
||||
in PRInt32 val,
|
||||
in PRUint32 count,
|
||||
[array, size_is(count)] inout PRInt32 valueArray);
|
||||
void MultiplyEachItemInIntegerArrayAndAppend(
|
||||
in PRInt32 val,
|
||||
inout PRUint32 count,
|
||||
[array, size_is(count)] inout PRInt32 valueArray);
|
||||
};
|
||||
|
||||
|
||||
@@ -56,38 +56,43 @@
|
||||
#define GENERATE_XPC_FAILURE(x) \
|
||||
(NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XPCONNECT,x))
|
||||
|
||||
#define NS_ERROR_XPC_NOT_ENOUGH_ARGS GENERATE_XPC_FAILURE( 1)
|
||||
#define NS_ERROR_XPC_NEED_OUT_OBJECT GENERATE_XPC_FAILURE( 2)
|
||||
#define NS_ERROR_XPC_CANT_SET_OUT_VAL GENERATE_XPC_FAILURE( 3)
|
||||
#define NS_ERROR_XPC_NATIVE_RETURNED_FAILURE GENERATE_XPC_FAILURE( 4)
|
||||
#define NS_ERROR_XPC_CANT_GET_INTERFACE_INFO GENERATE_XPC_FAILURE( 5)
|
||||
#define NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO GENERATE_XPC_FAILURE( 6)
|
||||
#define NS_ERROR_XPC_CANT_GET_METHOD_INFO GENERATE_XPC_FAILURE( 7)
|
||||
#define NS_ERROR_XPC_UNEXPECTED GENERATE_XPC_FAILURE( 8)
|
||||
#define NS_ERROR_XPC_BAD_CONVERT_JS GENERATE_XPC_FAILURE( 9)
|
||||
#define NS_ERROR_XPC_BAD_CONVERT_NATIVE GENERATE_XPC_FAILURE(10)
|
||||
#define NS_ERROR_XPC_BAD_CONVERT_JS_NULL_REF GENERATE_XPC_FAILURE(11)
|
||||
#define NS_ERROR_XPC_BAD_OP_ON_WN_PROTO GENERATE_XPC_FAILURE(12)
|
||||
#define NS_ERROR_XPC_CANT_CONVERT_WN_TO_FUN GENERATE_XPC_FAILURE(13)
|
||||
#define NS_ERROR_XPC_CANT_DEFINE_PROP_ON_WN GENERATE_XPC_FAILURE(14)
|
||||
#define NS_ERROR_XPC_CANT_WATCH_WN_STATIC GENERATE_XPC_FAILURE(15)
|
||||
#define NS_ERROR_XPC_CANT_EXPORT_WN_STATIC GENERATE_XPC_FAILURE(16)
|
||||
#define NS_ERROR_XPC_SCRIPTABLE_CALL_FAILED GENERATE_XPC_FAILURE(17)
|
||||
#define NS_ERROR_XPC_SCRIPTABLE_CTOR_FAILED GENERATE_XPC_FAILURE(18)
|
||||
#define NS_ERROR_XPC_CANT_CALL_WO_SCRIPTABLE GENERATE_XPC_FAILURE(19)
|
||||
#define NS_ERROR_XPC_CANT_CTOR_WO_SCRIPTABLE GENERATE_XPC_FAILURE(20)
|
||||
#define NS_ERROR_XPC_CI_RETURNED_FAILURE GENERATE_XPC_FAILURE(21)
|
||||
#define NS_ERROR_XPC_GS_RETURNED_FAILURE GENERATE_XPC_FAILURE(22)
|
||||
#define NS_ERROR_XPC_BAD_CID GENERATE_XPC_FAILURE(23)
|
||||
#define NS_ERROR_XPC_BAD_IID GENERATE_XPC_FAILURE(24)
|
||||
#define NS_ERROR_XPC_CANT_CREATE_WN GENERATE_XPC_FAILURE(25)
|
||||
#define NS_ERROR_XPC_JS_THREW_EXCEPTION GENERATE_XPC_FAILURE(26)
|
||||
#define NS_ERROR_XPC_JS_THREW_NATIVE_OBJECT GENERATE_XPC_FAILURE(27)
|
||||
#define NS_ERROR_XPC_JS_THREW_JS_OBJECT GENERATE_XPC_FAILURE(28)
|
||||
#define NS_ERROR_XPC_JS_THREW_NULL GENERATE_XPC_FAILURE(29)
|
||||
#define NS_ERROR_XPC_JS_THREW_STRING GENERATE_XPC_FAILURE(30)
|
||||
#define NS_ERROR_XPC_JAVASCRIPT_ERROR GENERATE_XPC_FAILURE(31)
|
||||
#define NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS GENERATE_XPC_FAILURE(32)
|
||||
#define NS_ERROR_XPC_NOT_ENOUGH_ARGS GENERATE_XPC_FAILURE( 1)
|
||||
#define NS_ERROR_XPC_NEED_OUT_OBJECT GENERATE_XPC_FAILURE( 2)
|
||||
#define NS_ERROR_XPC_CANT_SET_OUT_VAL GENERATE_XPC_FAILURE( 3)
|
||||
#define NS_ERROR_XPC_NATIVE_RETURNED_FAILURE GENERATE_XPC_FAILURE( 4)
|
||||
#define NS_ERROR_XPC_CANT_GET_INTERFACE_INFO GENERATE_XPC_FAILURE( 5)
|
||||
#define NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO GENERATE_XPC_FAILURE( 6)
|
||||
#define NS_ERROR_XPC_CANT_GET_METHOD_INFO GENERATE_XPC_FAILURE( 7)
|
||||
#define NS_ERROR_XPC_UNEXPECTED GENERATE_XPC_FAILURE( 8)
|
||||
#define NS_ERROR_XPC_BAD_CONVERT_JS GENERATE_XPC_FAILURE( 9)
|
||||
#define NS_ERROR_XPC_BAD_CONVERT_NATIVE GENERATE_XPC_FAILURE(10)
|
||||
#define NS_ERROR_XPC_BAD_CONVERT_JS_NULL_REF GENERATE_XPC_FAILURE(11)
|
||||
#define NS_ERROR_XPC_BAD_OP_ON_WN_PROTO GENERATE_XPC_FAILURE(12)
|
||||
#define NS_ERROR_XPC_CANT_CONVERT_WN_TO_FUN GENERATE_XPC_FAILURE(13)
|
||||
#define NS_ERROR_XPC_CANT_DEFINE_PROP_ON_WN GENERATE_XPC_FAILURE(14)
|
||||
#define NS_ERROR_XPC_CANT_WATCH_WN_STATIC GENERATE_XPC_FAILURE(15)
|
||||
#define NS_ERROR_XPC_CANT_EXPORT_WN_STATIC GENERATE_XPC_FAILURE(16)
|
||||
#define NS_ERROR_XPC_SCRIPTABLE_CALL_FAILED GENERATE_XPC_FAILURE(17)
|
||||
#define NS_ERROR_XPC_SCRIPTABLE_CTOR_FAILED GENERATE_XPC_FAILURE(18)
|
||||
#define NS_ERROR_XPC_CANT_CALL_WO_SCRIPTABLE GENERATE_XPC_FAILURE(19)
|
||||
#define NS_ERROR_XPC_CANT_CTOR_WO_SCRIPTABLE GENERATE_XPC_FAILURE(20)
|
||||
#define NS_ERROR_XPC_CI_RETURNED_FAILURE GENERATE_XPC_FAILURE(21)
|
||||
#define NS_ERROR_XPC_GS_RETURNED_FAILURE GENERATE_XPC_FAILURE(22)
|
||||
#define NS_ERROR_XPC_BAD_CID GENERATE_XPC_FAILURE(23)
|
||||
#define NS_ERROR_XPC_BAD_IID GENERATE_XPC_FAILURE(24)
|
||||
#define NS_ERROR_XPC_CANT_CREATE_WN GENERATE_XPC_FAILURE(25)
|
||||
#define NS_ERROR_XPC_JS_THREW_EXCEPTION GENERATE_XPC_FAILURE(26)
|
||||
#define NS_ERROR_XPC_JS_THREW_NATIVE_OBJECT GENERATE_XPC_FAILURE(27)
|
||||
#define NS_ERROR_XPC_JS_THREW_JS_OBJECT GENERATE_XPC_FAILURE(28)
|
||||
#define NS_ERROR_XPC_JS_THREW_NULL GENERATE_XPC_FAILURE(29)
|
||||
#define NS_ERROR_XPC_JS_THREW_STRING GENERATE_XPC_FAILURE(30)
|
||||
#define NS_ERROR_XPC_JS_THREW_NUMBER GENERATE_XPC_FAILURE(31)
|
||||
#define NS_ERROR_XPC_JAVASCRIPT_ERROR GENERATE_XPC_FAILURE(32)
|
||||
#define NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS GENERATE_XPC_FAILURE(33)
|
||||
#define NS_ERROR_XPC_CANT_CONVERT_PRIMITIVE_TO_ARRAY GENERATE_XPC_FAILURE(34)
|
||||
#define NS_ERROR_XPC_CANT_CONVERT_OBJECT_TO_ARRAY GENERATE_XPC_FAILURE(35)
|
||||
#define NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY GENERATE_XPC_FAILURE(36)
|
||||
#define NS_ERROR_XPC_CANT_GET_ARRAY_INFO GENERATE_XPC_FAILURE(37)
|
||||
|
||||
// any new errors here should have an associated entry added in xpc.msg
|
||||
|
||||
|
||||
@@ -21,38 +21,43 @@
|
||||
|
||||
/* xpconnect specific codes (from nsIXPConnect.h) */
|
||||
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_NOT_ENOUGH_ARGS , "Not enough arguments")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_NEED_OUT_OBJECT , "'Out' argument must be an object")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_SET_OUT_VAL , "Can not set 'value' property of 'out' argument")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_NATIVE_RETURNED_FAILURE , "Component returned failure code:")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_GET_INTERFACE_INFO , "Can not find interface information")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO , "Can not find interface information for parameter")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_GET_METHOD_INFO , "Can not find method information")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_UNEXPECTED , "Unexpected error in XPConnect")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_BAD_CONVERT_JS , "Could not convert JavaScript argument")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_BAD_CONVERT_NATIVE , "Could not convert Native argument")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_BAD_CONVERT_JS_NULL_REF , "Could not convert JavaScript argument (NULL value can not be used for a C++ reference type)")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO , "Illegal operation on WrappedNative prototype object")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_CONVERT_WN_TO_FUN , "Cannot convert WrappedNative to function")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_DEFINE_PROP_ON_WN , "Cannot define new property in a WrappedNative")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_WATCH_WN_STATIC , "Cannot place watchpoints on WrappedNative object static properties")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_EXPORT_WN_STATIC , "Cannot export a WrappedNative object's static properties")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_SCRIPTABLE_CALL_FAILED , "nsIXPCScriptable::Call failed")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_SCRIPTABLE_CTOR_FAILED , "nsIXPCScriptable::Construct failed")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_CALL_WO_SCRIPTABLE , "Can not use wrapper as function unless it implements nsIXPCScriptable")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_CTOR_WO_SCRIPTABLE , "Can not use wrapper as constuctor unless it implements nsIXPCScriptable")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CI_RETURNED_FAILURE , "ComponentManager::CreateInstance returned failure code:")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_GS_RETURNED_FAILURE , "ServiceManager::GetService returned failure code:")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_BAD_CID , "Invalid ClassID or ProgID")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_BAD_IID , "Invalid InterfaceID")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_CREATE_WN , "Can not create wrapper around native interface")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_EXCEPTION , "JavaScript component threw exception")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_NATIVE_OBJECT , "JavaScript component threw a native object that is not an exception")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_JS_OBJECT , "JavaScript component threw a JavaScript object")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_NULL , "JavaScript component threw a null value as an exception")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_STRING , "JavaScript component threw a string as an exception")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_JAVASCRIPT_ERROR , "JavaScript component caused a JavaScript error")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS, "JavaScript component caused a JavaScript error (detailed report attached)")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_NOT_ENOUGH_ARGS , "Not enough arguments")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_NEED_OUT_OBJECT , "'Out' argument must be an object")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_SET_OUT_VAL , "Can not set 'value' property of 'out' argument")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_NATIVE_RETURNED_FAILURE , "Component returned failure code:")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_GET_INTERFACE_INFO , "Can not find interface information")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO , "Can not find interface information for parameter")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_GET_METHOD_INFO , "Can not find method information")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_UNEXPECTED , "Unexpected error in XPConnect")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_BAD_CONVERT_JS , "Could not convert JavaScript argument")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_BAD_CONVERT_NATIVE , "Could not convert Native argument")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_BAD_CONVERT_JS_NULL_REF , "Could not convert JavaScript argument (NULL value can not be used for a C++ reference type)")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO , "Illegal operation on WrappedNative prototype object")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_CONVERT_WN_TO_FUN , "Cannot convert WrappedNative to function")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_DEFINE_PROP_ON_WN , "Cannot define new property in a WrappedNative")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_WATCH_WN_STATIC , "Cannot place watchpoints on WrappedNative object static properties")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_EXPORT_WN_STATIC , "Cannot export a WrappedNative object's static properties")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_SCRIPTABLE_CALL_FAILED , "nsIXPCScriptable::Call failed")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_SCRIPTABLE_CTOR_FAILED , "nsIXPCScriptable::Construct failed")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_CALL_WO_SCRIPTABLE , "Can not use wrapper as function unless it implements nsIXPCScriptable")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_CTOR_WO_SCRIPTABLE , "Can not use wrapper as constuctor unless it implements nsIXPCScriptable")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CI_RETURNED_FAILURE , "ComponentManager::CreateInstance returned failure code:")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_GS_RETURNED_FAILURE , "ServiceManager::GetService returned failure code:")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_BAD_CID , "Invalid ClassID or ProgID")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_BAD_IID , "Invalid InterfaceID")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_CREATE_WN , "Can not create wrapper around native interface")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_EXCEPTION , "JavaScript component threw exception")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_NATIVE_OBJECT , "JavaScript component threw a native object that is not an exception")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_JS_OBJECT , "JavaScript component threw a JavaScript object")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_NULL , "JavaScript component threw a null value as an exception")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_STRING , "JavaScript component threw a string as an exception")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_NUMBER , "JavaScript component threw a number as an exception")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_JAVASCRIPT_ERROR , "JavaScript component caused a JavaScript error")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS , "JavaScript component caused a JavaScript error (detailed report attached)")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_CONVERT_PRIMITIVE_TO_ARRAY, "Can not convert primitive JavaScript value into an array")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_CONVERT_OBJECT_TO_ARRAY , "Can not convert JavaScript object into an array")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY , "JavaScript Array does not have enough elements")
|
||||
XPC_MSG_DEF(NS_ERROR_XPC_CANT_GET_ARRAY_INFO , "Can not find array information")
|
||||
|
||||
/* common global codes (from nsError.h) */
|
||||
|
||||
@@ -70,7 +75,7 @@ XPC_MSG_DEF(NS_ERROR_UNEXPECTED , "Unexpected error")
|
||||
XPC_MSG_DEF(NS_ERROR_OUT_OF_MEMORY , "Out of Memory")
|
||||
XPC_MSG_DEF(NS_ERROR_ILLEGAL_VALUE , "Illegal value")
|
||||
XPC_MSG_DEF(NS_ERROR_INVALID_ARG , "Invalid argument")
|
||||
XPC_MSG_DEF(NS_ERROR_NO_AGGREGATION , "Component doe not support aggregation")
|
||||
XPC_MSG_DEF(NS_ERROR_NO_AGGREGATION , "Component does not support aggregation")
|
||||
XPC_MSG_DEF(NS_ERROR_NOT_AVAILABLE , "Component is not available")
|
||||
XPC_MSG_DEF(NS_ERROR_FACTORY_NOT_REGISTERED , "Factory not registered")
|
||||
XPC_MSG_DEF(NS_ERROR_FACTORY_NOT_LOADED , "Factory not loaded")
|
||||
|
||||
@@ -979,6 +979,23 @@ nsXPCComponents::GetStack(nsIJSStackFrameLocation * *aStack)
|
||||
return nsXPConnect::GetXPConnect()->GetCurrentJSStack(aStack);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents::GetManager(nsIComponentManager * *aManager)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aManager);
|
||||
|
||||
nsIComponentManager* cm;
|
||||
if(NS_FAILED(NS_GetGlobalComponentManager(&cm)))
|
||||
{
|
||||
*aManager = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
NS_IF_ADDREF(cm);
|
||||
*aManager = cm;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
|
||||
// XPC_IMPLEMENT_FORWARD_CREATE(nsXPCComponents)
|
||||
|
||||
@@ -40,32 +40,34 @@
|
||||
((uint8)((np_no) | ((p_no) << 1) | ((np_o) << 2) | ((p_o) << 3)))
|
||||
|
||||
/***********************************************************/
|
||||
#define XPC_FLAG_COUNT nsXPTType::T_INTERFACE_IS+1
|
||||
#define XPC_FLAG_COUNT nsXPTType::T_ARRAY_WITH_LENGTH+1
|
||||
|
||||
/* '1' means 'reflectable'. '0' means 'not reflectable'. */
|
||||
/* '1' means 'reflectable'. '0' means 'not reflectable'. */
|
||||
static uint8 xpc_reflectable_flags[XPC_FLAG_COUNT] = {
|
||||
/* 'p' stands for 'pointer' and 'o' stands for 'out' */
|
||||
/* !p&!o, p&!o, !p&o, p&o */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_I8 */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_I16 */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_I32 */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_I64 */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_U8 */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_U16 */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_U32 */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_U64 */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_FLOAT */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_DOUBLE */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_BOOL */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_CHAR */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_WCHAR */
|
||||
XPC_MK_FLAG( 0 , 0 , 0 , 0 ), /* T_VOID */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_IID */
|
||||
XPC_MK_FLAG( 0 , 0 , 0 , 0 ), /* T_BSTR */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_CHAR_STR */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_WCHAR_STR */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_INTERFACE */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ) /* T_INTERFACE_IS */
|
||||
/* 'p' stands for 'pointer' and 'o' stands for 'out' */
|
||||
/* !p&!o, p&!o, !p&o, p&o */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_I8 */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_I16 */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_I32 */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_I64 */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_U8 */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_U16 */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_U32 */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_U64 */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_FLOAT */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_DOUBLE */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_BOOL */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_CHAR */
|
||||
XPC_MK_FLAG( 1 , 1 , 1 , 0 ), /* T_WCHAR */
|
||||
XPC_MK_FLAG( 0 , 0 , 0 , 0 ), /* T_VOID */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_IID */
|
||||
XPC_MK_FLAG( 0 , 0 , 0 , 0 ), /* T_BSTR */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_CHAR_STR */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_WCHAR_STR */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_INTERFACE */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_INTERFACE_IS */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ), /* T_ARRAY */
|
||||
XPC_MK_FLAG( 0 , 1 , 0 , 1 ) /* T_ARRAY_WITH_LENGTH */
|
||||
};
|
||||
/***********************************************************/
|
||||
|
||||
@@ -168,7 +170,7 @@ JAM_DOUBLE(JSContext *cx, double v, jsdouble *dbl)
|
||||
JSBool
|
||||
XPCConvert::NativeData2JS(JSContext* cx, jsval* d, const void* s,
|
||||
const nsXPTType& type, const nsID* iid,
|
||||
uintN* pErr)
|
||||
nsresult* pErr)
|
||||
{
|
||||
NS_PRECONDITION(s, "bad param");
|
||||
NS_PRECONDITION(d, "bad param");
|
||||
@@ -365,7 +367,7 @@ JSBool
|
||||
XPCConvert::JSData2Native(JSContext* cx, void* d, jsval s,
|
||||
const nsXPTType& type,
|
||||
JSBool useAllocator, const nsID* iid,
|
||||
uintN* pErr)
|
||||
nsresult* pErr)
|
||||
{
|
||||
NS_PRECONDITION(d, "bad param");
|
||||
|
||||
@@ -755,7 +757,7 @@ XPCConvert::JSValToXPCException(JSContext* cx,
|
||||
// heuristic to see if it might be usable as an xpcexception
|
||||
if(JS_GetPropertyAttributes(cx, obj, "message", &ignored, &found) &&
|
||||
found &&
|
||||
JS_GetPropertyAttributes(cx, obj, "code", &ignored, &found) &&
|
||||
JS_GetPropertyAttributes(cx, obj, "result", &ignored, &found) &&
|
||||
found)
|
||||
{
|
||||
// lets try to build a wrapper around the JSObject
|
||||
@@ -786,12 +788,59 @@ XPCConvert::JSValToXPCException(JSContext* cx,
|
||||
nsnull, ifaceName, methodName, nsnull);
|
||||
}
|
||||
|
||||
// lets see if it looks like and nsresult
|
||||
if(JSVAL_IS_NUMBER(s))
|
||||
{
|
||||
// lets see if it looks like an nsresult
|
||||
nsresult rv;
|
||||
double number;
|
||||
JSBool isResult = JS_FALSE;
|
||||
|
||||
nsresult rv;
|
||||
if(JSVAL_IS_NUMBER(s) && JS_ValueToECMAUint32(cx, s, (uint32*)&rv))
|
||||
return ConstructException(rv, nsnull, ifaceName, methodName, nsnull);
|
||||
if(JSVAL_IS_INT(s))
|
||||
{
|
||||
rv = (nsresult) JSVAL_TO_INT(s);
|
||||
if(NS_FAILED(rv))
|
||||
isResult = JS_TRUE;
|
||||
else
|
||||
number = (double) JSVAL_TO_INT(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(JSVAL_TO_DOUBLE(s))
|
||||
{
|
||||
number = *(JSVAL_TO_DOUBLE(s));
|
||||
if(number > 0.0 &&
|
||||
number < (double)0xffffffff &&
|
||||
0.0 == fmod(number,1))
|
||||
{
|
||||
rv = (nsresult) number;
|
||||
if(NS_FAILED(rv))
|
||||
isResult = JS_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isResult)
|
||||
return ConstructException(rv, nsnull, ifaceName, methodName, nsnull);
|
||||
else
|
||||
{
|
||||
nsISupportsDouble* data;
|
||||
nsIComponentManager* cm;
|
||||
if(NS_FAILED(NS_GetGlobalComponentManager(&cm)) || !cm ||
|
||||
NS_FAILED(cm->CreateInstanceByProgID(
|
||||
NS_SUPPORTS_DOUBLE_PROGID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsISupportsDouble),
|
||||
(void**)&data)))
|
||||
return nsnull;
|
||||
data->SetData(number);
|
||||
nsIXPCException* e =
|
||||
ConstructException(NS_ERROR_XPC_JS_THREW_NUMBER,
|
||||
nsnull,
|
||||
ifaceName, methodName, data);
|
||||
NS_RELEASE(data);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise we'll just try to convert it to a string
|
||||
|
||||
@@ -882,3 +931,244 @@ XPC_JSArgumentFormatter(JSContext *cx, const char *format,
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
XPCArrayDataScavenger::XPCArrayDataScavenger(XPCArrayDataScavenger* aNext)
|
||||
: mCleanupMode(NO_ACTION),
|
||||
mInitedCount(0),
|
||||
mData(nsnull),
|
||||
mNext(aNext)
|
||||
{
|
||||
// nada
|
||||
}
|
||||
|
||||
XPCArrayDataScavenger::~XPCArrayDataScavenger()
|
||||
{
|
||||
if(mData)
|
||||
{
|
||||
if(mCleanupMode == DO_FREE)
|
||||
{
|
||||
for(PRUint32 i = 0; i < mInitedCount; i++)
|
||||
{
|
||||
void* p = mData[i];
|
||||
if(p) nsAllocator::Free(p);
|
||||
}
|
||||
}
|
||||
else if(mCleanupMode == DO_RELEASE)
|
||||
{
|
||||
for(PRUint32 i = 0; i < mInitedCount; i++)
|
||||
{
|
||||
nsISupports* p = NS_REINTERPRET_CAST(nsISupports*, mData[i]);
|
||||
NS_IF_RELEASE(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(mNext)
|
||||
delete mNext;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
// array fun...
|
||||
|
||||
#ifdef POPULATE
|
||||
#undef POPULATE
|
||||
#endif
|
||||
|
||||
// static
|
||||
JSBool
|
||||
XPCConvert::NativeArray2JS(JSContext* cx,
|
||||
jsval* d, const void** s,
|
||||
const nsXPTType& type, const nsID* iid,
|
||||
JSUint32 count,
|
||||
nsresult* pErr)
|
||||
{
|
||||
NS_PRECONDITION(s, "bad param");
|
||||
NS_PRECONDITION(d, "bad param");
|
||||
|
||||
// XXX add support for putting chars in a string rather than an array
|
||||
|
||||
// XXX add support to indicate *which* array element was not convertable
|
||||
|
||||
JSObject *array = JS_NewArrayObject(cx, count, nsnull);
|
||||
|
||||
if(!array)
|
||||
return JS_FALSE;
|
||||
|
||||
// root this early
|
||||
*d = OBJECT_TO_JSVAL(array);
|
||||
|
||||
if(pErr)
|
||||
*pErr = NS_ERROR_XPC_BAD_CONVERT_NATIVE;
|
||||
|
||||
JSUint32 i;
|
||||
jsval current;
|
||||
|
||||
#define POPULATE(_t) \
|
||||
PR_BEGIN_MACRO \
|
||||
for(i = 0; i < count; i++) \
|
||||
{ \
|
||||
if(!NativeData2JS(cx, ¤t, ((_t*)*s)+i, type, iid, pErr) || \
|
||||
!JS_SetElement(cx, array, i, ¤t)) \
|
||||
goto failure; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
// XXX check IsPtr - esp. to handle array of nsID (as opposed to nsID*)
|
||||
|
||||
switch(type.TagPart())
|
||||
{
|
||||
case nsXPTType::T_I8 : POPULATE(int8); break;
|
||||
case nsXPTType::T_I16 : POPULATE(int16); break;
|
||||
case nsXPTType::T_I32 : POPULATE(int32); break;
|
||||
case nsXPTType::T_I64 : POPULATE(int64); break;
|
||||
case nsXPTType::T_U8 : POPULATE(uint8); break;
|
||||
case nsXPTType::T_U16 : POPULATE(uint16); break;
|
||||
case nsXPTType::T_U32 : POPULATE(uint32); break;
|
||||
case nsXPTType::T_U64 : POPULATE(uint64); break;
|
||||
case nsXPTType::T_FLOAT : POPULATE(float); break;
|
||||
case nsXPTType::T_DOUBLE : POPULATE(double); break;
|
||||
case nsXPTType::T_BOOL : POPULATE(PRBool); break;
|
||||
case nsXPTType::T_CHAR : POPULATE(char); break;
|
||||
case nsXPTType::T_WCHAR : POPULATE(jschar); break;
|
||||
case nsXPTType::T_VOID : NS_ASSERTION(0,"bad type"); goto failure;
|
||||
case nsXPTType::T_IID : POPULATE(nsID*); break;
|
||||
case nsXPTType::T_BSTR : NS_ASSERTION(0,"bad type"); goto failure;
|
||||
case nsXPTType::T_CHAR_STR : POPULATE(char*); break;
|
||||
case nsXPTType::T_WCHAR_STR : POPULATE(jschar*); break;
|
||||
case nsXPTType::T_INTERFACE : POPULATE(nsISupports*); break;
|
||||
case nsXPTType::T_INTERFACE_IS : POPULATE(nsISupports*); break;
|
||||
default : NS_ASSERTION(0,"bad type"); goto failure;
|
||||
}
|
||||
|
||||
if(pErr)
|
||||
*pErr = NS_OK;
|
||||
return JS_TRUE;
|
||||
|
||||
failure:
|
||||
return JS_FALSE;
|
||||
|
||||
#undef POPULATE
|
||||
}
|
||||
|
||||
// static
|
||||
JSBool
|
||||
XPCConvert::JSArray2Native(JSContext* cx, void** d, jsval s,
|
||||
JSUint32 count, JSUint32 capacity,
|
||||
XPCArrayDataScavenger* scavenger,
|
||||
const nsXPTType& type,
|
||||
JSBool useAllocator, const nsID* iid,
|
||||
uintN* pErr)
|
||||
{
|
||||
NS_PRECONDITION(d, "bad param");
|
||||
NS_PRECONDITION(scavenger, "bad param");
|
||||
|
||||
|
||||
// XXX add support for getting chars from strings
|
||||
|
||||
// XXX add support to indicate *which* array element was not convertable
|
||||
|
||||
if(JSVAL_IS_VOID(s) || JSVAL_IS_NULL(s))
|
||||
{
|
||||
*d = nsnull;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
if(!JSVAL_IS_OBJECT(s))
|
||||
{
|
||||
if(pErr)
|
||||
*pErr = NS_ERROR_XPC_CANT_CONVERT_PRIMITIVE_TO_ARRAY;
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSObject* jsarray = JSVAL_TO_OBJECT(s);
|
||||
if(!JS_IsArrayObject(cx, jsarray))
|
||||
{
|
||||
if(pErr)
|
||||
*pErr = NS_ERROR_XPC_CANT_CONVERT_OBJECT_TO_ARRAY;
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
jsuint len;
|
||||
if(!JS_GetArrayLength(cx, jsarray, &len) || len < count)
|
||||
{
|
||||
if(pErr)
|
||||
*pErr = NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY;
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if(pErr)
|
||||
*pErr = NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
|
||||
void* array = nsnull;
|
||||
JSUint32 i;
|
||||
jsval current;
|
||||
|
||||
#define POPULATE(_mode, _t) \
|
||||
PR_BEGIN_MACRO \
|
||||
if(nsnull == (array = nsAllocator::Alloc(capacity * sizeof(_t)))) \
|
||||
{ \
|
||||
if(pErr) \
|
||||
*pErr = NS_ERROR_OUT_OF_MEMORY; \
|
||||
goto failure; \
|
||||
} \
|
||||
scavenger->SetDataPtr((void**)array); \
|
||||
scavenger->SetCleanupMode(_mode); \
|
||||
for(i = 0; i < count; i++) \
|
||||
{ \
|
||||
if(!JS_GetElement(cx, jsarray, i, ¤t) || \
|
||||
!JSData2Native(cx, ((_t*)array)+i, current, type, \
|
||||
useAllocator, iid, pErr)) \
|
||||
goto failure; \
|
||||
scavenger->IncrementInitedCount(); \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
static const XPCArrayDataScavenger::CleanupMode
|
||||
na = XPCArrayDataScavenger::NO_ACTION,
|
||||
fr = useAllocator ?
|
||||
XPCArrayDataScavenger::DO_FREE :
|
||||
XPCArrayDataScavenger::NO_ACTION,
|
||||
re = XPCArrayDataScavenger::DO_RELEASE;
|
||||
|
||||
// XXX check IsPtr - esp. to handle array of nsID (as opposed to nsID*)
|
||||
|
||||
// XXX make extra space at end of char* and wchar* and null termintate
|
||||
|
||||
switch(type.TagPart())
|
||||
{
|
||||
case nsXPTType::T_I8 : POPULATE(na, int8); break;
|
||||
case nsXPTType::T_I16 : POPULATE(na, int16); break;
|
||||
case nsXPTType::T_I32 : POPULATE(na, int32); break;
|
||||
case nsXPTType::T_I64 : POPULATE(na, int64); break;
|
||||
case nsXPTType::T_U8 : POPULATE(na, uint8); break;
|
||||
case nsXPTType::T_U16 : POPULATE(na, uint16); break;
|
||||
case nsXPTType::T_U32 : POPULATE(na, uint32); break;
|
||||
case nsXPTType::T_U64 : POPULATE(na, uint64); break;
|
||||
case nsXPTType::T_FLOAT : POPULATE(na, float); break;
|
||||
case nsXPTType::T_DOUBLE : POPULATE(na, double); break;
|
||||
case nsXPTType::T_BOOL : POPULATE(na, PRBool); break;
|
||||
case nsXPTType::T_CHAR : POPULATE(na, char); break;
|
||||
case nsXPTType::T_WCHAR : POPULATE(na, jschar); break;
|
||||
case nsXPTType::T_VOID : NS_ASSERTION(0,"bad type"); goto failure;
|
||||
case nsXPTType::T_IID : POPULATE(fr, nsID*); break;
|
||||
case nsXPTType::T_BSTR : NS_ASSERTION(0,"bad type"); goto failure;
|
||||
case nsXPTType::T_CHAR_STR : POPULATE(fr, char*); break;
|
||||
case nsXPTType::T_WCHAR_STR : POPULATE(fr, jschar*); break;
|
||||
case nsXPTType::T_INTERFACE : POPULATE(re, nsISupports*); break;
|
||||
case nsXPTType::T_INTERFACE_IS : POPULATE(re, nsISupports*); break;
|
||||
default : NS_ASSERTION(0,"bad type"); goto failure;
|
||||
}
|
||||
|
||||
*d = array;
|
||||
if(pErr)
|
||||
*pErr = NS_OK;
|
||||
return JS_TRUE;
|
||||
|
||||
failure:
|
||||
return JS_FALSE;
|
||||
|
||||
#undef POPULATE
|
||||
}
|
||||
|
||||
|
||||
@@ -619,6 +619,19 @@ private:
|
||||
JSBool BuildMemberDescriptors();
|
||||
void DestroyMemberDescriptors();
|
||||
|
||||
|
||||
enum SizeMode {GET_SIZE, GET_LENGTH};
|
||||
|
||||
JSBool GetArraySizeFromParam(JSContext* cx,
|
||||
const nsXPTMethodInfo* method,
|
||||
const XPCNativeMemberDescriptor* desc,
|
||||
const nsXPTParamInfo& param,
|
||||
uint8 vtblIndex,
|
||||
uint8 paramIndex,
|
||||
SizeMode mode,
|
||||
jsval *argv,
|
||||
JSUint32* result);
|
||||
|
||||
private:
|
||||
XPCContext* mXPCContext;
|
||||
nsIID mIID;
|
||||
@@ -703,6 +716,32 @@ public:
|
||||
/***************************************************************************/
|
||||
// data convertion
|
||||
|
||||
class XPCArrayDataScavenger
|
||||
{
|
||||
public:
|
||||
enum CleanupMode {NO_ACTION, DO_FREE, DO_RELEASE};
|
||||
|
||||
void SetDataPtr(void** aData)
|
||||
{NS_ASSERTION(!mData,"must set data only once"); mData = aData;}
|
||||
void SetCleanupMode(CleanupMode aCleanupMode)
|
||||
{mCleanupMode = aCleanupMode;}
|
||||
void IncrementInitedCount()
|
||||
{NS_ASSERTION(mData,"must set data first"); mInitedCount++;}
|
||||
|
||||
XPCArrayDataScavenger(XPCArrayDataScavenger* aNext);
|
||||
|
||||
~XPCArrayDataScavenger();
|
||||
|
||||
private:
|
||||
XPCArrayDataScavenger(); // no implementation
|
||||
|
||||
private:
|
||||
CleanupMode mCleanupMode;
|
||||
PRUint32 mInitedCount;
|
||||
void** mData;
|
||||
XPCArrayDataScavenger* mNext;
|
||||
};
|
||||
|
||||
// class here just for static methods
|
||||
class XPCConvert
|
||||
{
|
||||
@@ -711,12 +750,25 @@ public:
|
||||
|
||||
static JSBool NativeData2JS(JSContext* cx, jsval* d, const void* s,
|
||||
const nsXPTType& type, const nsID* iid,
|
||||
uintN* pErr);
|
||||
nsresult* pErr);
|
||||
|
||||
static JSBool JSData2Native(JSContext* cx, void* d, jsval s,
|
||||
const nsXPTType& type,
|
||||
JSBool useAllocator, const nsID* iid,
|
||||
uintN* pErr);
|
||||
nsresult* pErr);
|
||||
|
||||
static JSBool NativeArray2JS(JSContext* cx,
|
||||
jsval* d, const void** s,
|
||||
const nsXPTType& type, const nsID* iid,
|
||||
JSUint32 count,
|
||||
nsresult* pErr);
|
||||
|
||||
static JSBool JSArray2Native(JSContext* cx, void** d, jsval s,
|
||||
JSUint32 count, JSUint32 capacity,
|
||||
XPCArrayDataScavenger* scavenger,
|
||||
const nsXPTType& type,
|
||||
JSBool useAllocator, const nsID* iid,
|
||||
uintN* pErr);
|
||||
|
||||
static nsIXPCException* JSValToXPCException(JSContext* cx,
|
||||
jsval s,
|
||||
@@ -889,9 +941,10 @@ public:
|
||||
|
||||
/***************************************************************************/
|
||||
// a class to put on the stack when we are entering xpconnect from an entry
|
||||
// point where the JSContext is known. This pushes and pops the given context
|
||||
// point where the JSContext is known. This pushs and pops the given context
|
||||
// with the nsThreadJSContextStack service as this object goes into and out
|
||||
// of scope.
|
||||
// of scope. It is optimized to not push/pop the cx if it is already on top
|
||||
// of the stack.
|
||||
|
||||
class AutoPushJSContext
|
||||
{
|
||||
|
||||
@@ -188,6 +188,13 @@ nsXPCWrappedJS::nsXPCWrappedJS(JSObject* aJSObj,
|
||||
mRoot(root ? root : this),
|
||||
mNext(nsnull)
|
||||
{
|
||||
#ifdef DEBUG_stats_jband
|
||||
static int count = 0;
|
||||
static const int interval = 10;
|
||||
if(0 == (++count % interval))
|
||||
printf("//////// %d instances of nsXPCWrappedJS created\n", count);
|
||||
#endif
|
||||
|
||||
NS_INIT_REFCNT();
|
||||
NS_ADDREF_THIS();
|
||||
NS_ADDREF(aClass);
|
||||
|
||||
@@ -320,6 +320,13 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16 methodIndex,
|
||||
void* mark;
|
||||
nsXPConnect* xpc = nsXPConnect::GetXPConnect();
|
||||
|
||||
#ifdef DEBUG_stats_jband
|
||||
static int count = 0;
|
||||
static const int interval = 10;
|
||||
if(0 == (++count % interval))
|
||||
printf("<<<<<<<< %d calls on nsXPCWrappedJSs made\n", count);
|
||||
#endif
|
||||
|
||||
// XXX ASSUMES that retval is last arg.
|
||||
paramCount = info->GetParamCount();
|
||||
argc = paramCount -
|
||||
@@ -519,6 +526,8 @@ pre_call_clean_up:
|
||||
|
||||
/* this one would be set by our error reporter */
|
||||
xpc_exception = mXPCContext->GetException();
|
||||
if(xpc_exception)
|
||||
mXPCContext->SetException(nsnull);
|
||||
|
||||
// get this right away in case we do something below to cause JS code
|
||||
// to run on this JSContext
|
||||
@@ -542,22 +551,17 @@ pre_call_clean_up:
|
||||
|
||||
if(xpc_exception)
|
||||
{
|
||||
// Only throw the exception and fail if the JS code threw something
|
||||
// that does indicate a failure; i.e. 'throw 0' is not really a failure
|
||||
nsresult e_result;
|
||||
if(NS_SUCCEEDED(xpc_exception->GetResult(&e_result)) && NS_FAILED(e_result))
|
||||
if(NS_SUCCEEDED(xpc_exception->GetResult(&e_result)))
|
||||
{
|
||||
xpc->SetPendingException(xpc_exception);
|
||||
NS_RELEASE(xpc_exception);
|
||||
mXPCContext->SetException(nsnull);
|
||||
retval = e_result;
|
||||
success = JS_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pending_result = e_result;
|
||||
NS_RELEASE(xpc_exception);
|
||||
if(NS_FAILED(e_result))
|
||||
{
|
||||
xpc->SetPendingException(xpc_exception);
|
||||
retval = e_result;
|
||||
}
|
||||
}
|
||||
NS_RELEASE(xpc_exception);
|
||||
success = JS_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -238,6 +238,13 @@ nsXPCWrappedNative::nsXPCWrappedNative(nsISupports* aObj,
|
||||
NS_ADDREF(aClass);
|
||||
NS_ADDREF(aObj);
|
||||
|
||||
#ifdef DEBUG_stats_jband
|
||||
static int count = 0;
|
||||
static const int interval = 10;
|
||||
if(0 == (++count % interval))
|
||||
printf("++++++++ %d instances of nsXPCWrappedNative created\n", count);
|
||||
#endif
|
||||
|
||||
if(mRoot == this)
|
||||
{
|
||||
nsIXPCScriptable* ds;
|
||||
|
||||
@@ -288,6 +288,68 @@ nsXPCWrappedNativeClass::GetConstantAsJSVal(JSContext *cx,
|
||||
return XPCConvert::NativeData2JS(cx, vp, &v.val, v.type, nsnull, nsnull);
|
||||
}
|
||||
|
||||
JSBool
|
||||
nsXPCWrappedNativeClass::GetArraySizeFromParam(
|
||||
JSContext* cx,
|
||||
const nsXPTMethodInfo* method,
|
||||
const XPCNativeMemberDescriptor* desc,
|
||||
const nsXPTParamInfo& param,
|
||||
uint8 vtblIndex,
|
||||
uint8 paramIndex,
|
||||
SizeMode mode,
|
||||
jsval *argv,
|
||||
JSUint32* result)
|
||||
{
|
||||
uint8 argnum;
|
||||
nsresult rv;
|
||||
jsval val;
|
||||
|
||||
// XXX fixup the various exceptions that are thrown
|
||||
|
||||
if(mode == GET_SIZE)
|
||||
rv = mInfo->GetSizeIsArgNumberForParam(vtblIndex, ¶m, 1, &argnum);
|
||||
else
|
||||
rv = mInfo->GetLengthIsArgNumberForParam(vtblIndex, ¶m, 1, &argnum);
|
||||
if(NS_FAILED(rv))
|
||||
{
|
||||
ThrowException(NS_ERROR_XPC_CANT_GET_ARRAY_INFO, cx, desc);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
const nsXPTParamInfo& arg_param = method->GetParam(argnum);
|
||||
const nsXPTType& arg_type = arg_param.GetType();
|
||||
|
||||
// XXX require PRUint32 here - need to require in compiler too!
|
||||
if(arg_type.IsPointer() || arg_type.TagPart() != nsXPTType::T_U32)
|
||||
{
|
||||
ThrowException(NS_ERROR_XPC_CANT_GET_ARRAY_INFO, cx, desc);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if(arg_param.IsOut())
|
||||
{
|
||||
if(JSVAL_IS_PRIMITIVE(argv[argnum]) ||
|
||||
!JS_GetProperty(cx, JSVAL_TO_OBJECT(argv[argnum]),
|
||||
XPC_VAL_STR, &val))
|
||||
{
|
||||
ThrowException(NS_ERROR_XPC_CANT_GET_ARRAY_INFO, cx, desc);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
val = argv[argnum];
|
||||
}
|
||||
if(!XPCConvert::JSData2Native(cx, result, val,
|
||||
arg_type, JS_FALSE, nsnull, nsnull))
|
||||
{
|
||||
ThrowBadParamException(NS_ERROR_XPC_CANT_GET_ARRAY_INFO,
|
||||
cx, desc, paramIndex);
|
||||
return JS_FALSE;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool
|
||||
nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
|
||||
nsXPCWrappedNative* wrapper,
|
||||
@@ -313,6 +375,14 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
|
||||
uintN err;
|
||||
XPCContext* xpcc = nsXPConnect::GetContext(cx);
|
||||
nsIXPCSecurityManager* securityManager;
|
||||
XPCArrayDataScavenger* scavenger = nsnull;
|
||||
|
||||
#ifdef DEBUG_stats_jband
|
||||
static int count = 0;
|
||||
static const int interval = 10;
|
||||
if(0 == (++count % interval))
|
||||
printf(">>>>>>>> %d calls on nsXPCWrappedNatives made\n", count);
|
||||
#endif
|
||||
|
||||
if(vp)
|
||||
*vp = JSVAL_NULL;
|
||||
@@ -415,6 +485,18 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
|
||||
JSBool useAllocator = JS_FALSE;
|
||||
const nsXPTParamInfo& param = info->GetParam(i);
|
||||
const nsXPTType& type = param.GetType();
|
||||
nsXPTType type_in_array = type;
|
||||
uint8 type_tag = type.TagPart();
|
||||
PRBool isArray = type.IsArray();
|
||||
JSUint32 array_count;
|
||||
JSUint32 array_capacity;
|
||||
|
||||
if(isArray && NS_FAILED(mInfo->GetTypeForParam(vtblIndex, ¶m, 1,
|
||||
&type_in_array)))
|
||||
{
|
||||
ThrowException(NS_ERROR_XPC_CANT_GET_ARRAY_INFO, cx, desc);
|
||||
goto done;
|
||||
}
|
||||
|
||||
nsXPTCVariant* dp = &dispatchParams[i];
|
||||
dp->type = type;
|
||||
@@ -422,8 +504,8 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
|
||||
dp->val.p = nsnull;
|
||||
dispatchParamsInitedCount++;
|
||||
|
||||
if(type.TagPart() == nsXPTType::T_INTERFACE ||
|
||||
type.TagPart() == nsXPTType::T_INTERFACE_IS)
|
||||
if(type_tag == nsXPTType::T_INTERFACE ||
|
||||
type_tag == nsXPTType::T_INTERFACE_IS)
|
||||
{
|
||||
dp->flags |= nsXPTCVariant::VAL_IS_IFACE;
|
||||
}
|
||||
@@ -444,12 +526,26 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
|
||||
cx, desc, i);
|
||||
goto done;
|
||||
}
|
||||
if(type.IsPointer() &&
|
||||
!type.IsInterfacePointer() &&
|
||||
!param.IsShared())
|
||||
|
||||
if(isArray)
|
||||
{
|
||||
useAllocator = JS_TRUE;
|
||||
dp->flags |= nsXPTCVariant::VAL_IS_OWNED;
|
||||
if(type_in_array.IsPointer() &&
|
||||
!type_in_array.IsInterfacePointer() &&
|
||||
!param.IsShared())
|
||||
{
|
||||
useAllocator = JS_TRUE;
|
||||
dp->flags |= nsXPTCVariant::VAL_IS_OWNED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(type.IsPointer() &&
|
||||
!type.IsInterfacePointer() &&
|
||||
!param.IsShared())
|
||||
{
|
||||
useAllocator = JS_TRUE;
|
||||
dp->flags |= nsXPTCVariant::VAL_IS_OWNED;
|
||||
}
|
||||
}
|
||||
if(!param.IsIn())
|
||||
continue;
|
||||
@@ -457,14 +553,45 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
|
||||
else
|
||||
{
|
||||
src = argv[i];
|
||||
if(type.IsPointer() && type.TagPart() == nsXPTType::T_IID)
|
||||
|
||||
if(isArray)
|
||||
{
|
||||
useAllocator = JS_TRUE;
|
||||
dp->flags |= nsXPTCVariant::VAL_IS_OWNED;
|
||||
if(type_in_array.IsPointer() &&
|
||||
type_in_array.TagPart() == nsXPTType::T_IID)
|
||||
{
|
||||
useAllocator = JS_TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(type.IsPointer() && type_tag == nsXPTType::T_IID)
|
||||
{
|
||||
useAllocator = JS_TRUE;
|
||||
dp->flags |= nsXPTCVariant::VAL_IS_OWNED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(type.TagPart() == nsXPTType::T_INTERFACE)
|
||||
|
||||
if(isArray)
|
||||
{
|
||||
if(!GetArraySizeFromParam(cx, info, desc, param, vtblIndex,
|
||||
i, GET_SIZE, argv, &array_capacity))
|
||||
goto done;
|
||||
|
||||
// XXX add code to handle length here!
|
||||
|
||||
array_count = array_capacity;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// XXX fix for arrays of interfaces!
|
||||
// Need to fix GetInterfaceIsArgNumber() to be a method on the
|
||||
// interface info instead of the param - so it can look at the right
|
||||
// type info.
|
||||
|
||||
if(type_tag == nsXPTType::T_INTERFACE)
|
||||
{
|
||||
if(NS_FAILED(GetInterfaceInfo()->
|
||||
GetIIDForParam(vtblIndex, ¶m, &conditional_iid)))
|
||||
@@ -474,14 +601,15 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else if(type.TagPart() == nsXPTType::T_INTERFACE_IS)
|
||||
else if(type_tag == nsXPTType::T_INTERFACE_IS)
|
||||
{
|
||||
uint8 arg_num = param.GetInterfaceIsArgNumber();
|
||||
const nsXPTParamInfo& param = info->GetParam(arg_num);
|
||||
const nsXPTType& type = param.GetType();
|
||||
if(!type.IsPointer() || type.TagPart() != nsXPTType::T_IID ||
|
||||
const nsXPTParamInfo& arg_param = info->GetParam(arg_num);
|
||||
const nsXPTType& arg_type = arg_param.GetType();
|
||||
if(!arg_type.IsPointer() ||
|
||||
arg_type.TagPart() != nsXPTType::T_IID ||
|
||||
!XPCConvert::JSData2Native(cx, &conditional_iid, argv[arg_num],
|
||||
type, JS_TRUE, nsnull, nsnull))
|
||||
arg_type, JS_TRUE, nsnull, nsnull))
|
||||
{
|
||||
ThrowBadParamException(NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO,
|
||||
cx, desc, i);
|
||||
@@ -489,12 +617,38 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
|
||||
}
|
||||
}
|
||||
|
||||
if(!XPCConvert::JSData2Native(cx, &dp->val, src, type,
|
||||
useAllocator, conditional_iid, &err))
|
||||
{
|
||||
ThrowBadParamException(err, cx, desc, i);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if(isArray)
|
||||
{
|
||||
XPCArrayDataScavenger* new_scavenger;
|
||||
if(!(new_scavenger = new XPCArrayDataScavenger(scavenger)))
|
||||
{
|
||||
JS_ReportOutOfMemory(cx);
|
||||
goto done;
|
||||
}
|
||||
scavenger = new_scavenger;
|
||||
|
||||
if(!XPCConvert::JSArray2Native(cx, (void**)&dp->val, src,
|
||||
array_count, array_capacity,
|
||||
scavenger, type_in_array,
|
||||
useAllocator, conditional_iid, &err))
|
||||
{
|
||||
// XXX need exception scheme for arrays to indicate bad element
|
||||
ThrowBadParamException(err, cx, desc, i);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!XPCConvert::JSData2Native(cx, &dp->val, src, type,
|
||||
useAllocator, conditional_iid, &err))
|
||||
{
|
||||
ThrowBadParamException(err, cx, desc, i);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if(conditional_iid)
|
||||
{
|
||||
nsAllocator::Free((void*)conditional_iid);
|
||||
@@ -522,6 +676,53 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
|
||||
if(param.IsOut())
|
||||
{
|
||||
jsval v;
|
||||
JSUint32 array_count;
|
||||
JSUint32 array_capacity;
|
||||
nsXPTType type_in_array;
|
||||
PRBool isArray = type.IsArray();
|
||||
|
||||
if(isArray)
|
||||
{
|
||||
uint8 size_is_argnum;
|
||||
|
||||
if(NS_FAILED(mInfo->GetTypeForParam(vtblIndex, ¶m, 1,
|
||||
&type_in_array)))
|
||||
{
|
||||
ThrowException(NS_ERROR_XPC_CANT_GET_ARRAY_INFO, cx, desc);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if(NS_FAILED(
|
||||
mInfo->GetSizeIsArgNumberForParam(vtblIndex, ¶m, 1,
|
||||
&size_is_argnum)))
|
||||
{
|
||||
ThrowException(NS_ERROR_XPC_CANT_GET_ARRAY_INFO, cx, desc);
|
||||
goto done;
|
||||
}
|
||||
const nsXPTParamInfo& arg_param = info->GetParam(size_is_argnum);
|
||||
const nsXPTType& arg_type = arg_param.GetType();
|
||||
// XXX require PRUint32 here - need to require in compiler too!
|
||||
if(arg_type.IsPointer() ||
|
||||
arg_type.TagPart() != nsXPTType::T_U32)
|
||||
{
|
||||
ThrowBadParamException(NS_ERROR_XPC_CANT_GET_ARRAY_INFO,
|
||||
cx, desc, i);
|
||||
goto done;
|
||||
}
|
||||
array_capacity = dispatchParams[size_is_argnum].val.u32;
|
||||
|
||||
// XXX add code to handle length here!
|
||||
|
||||
array_count = array_capacity;
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// XXX fix for arrays of interfaces!
|
||||
// Need to fix GetInterfaceIsArgNumber() to be a method on the
|
||||
// interface info instead of the param - so it can look at the right
|
||||
// type info.
|
||||
|
||||
if(type.TagPart() == nsXPTType::T_INTERFACE)
|
||||
{
|
||||
@@ -536,9 +737,10 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
|
||||
else if(type.TagPart() == nsXPTType::T_INTERFACE_IS)
|
||||
{
|
||||
uint8 arg_num = param.GetInterfaceIsArgNumber();
|
||||
const nsXPTParamInfo& param = info->GetParam(arg_num);
|
||||
const nsXPTType& type = param.GetType();
|
||||
if(!type.IsPointer() || type.TagPart() != nsXPTType::T_IID ||
|
||||
const nsXPTParamInfo& arg_param = info->GetParam(arg_num);
|
||||
const nsXPTType& arg_type = arg_param.GetType();
|
||||
if(!arg_type.IsPointer() ||
|
||||
arg_type.TagPart() != nsXPTType::T_IID ||
|
||||
!(conditional_iid = (nsID*)
|
||||
nsAllocator::Clone(dispatchParams[arg_num].val.p,
|
||||
sizeof(nsID))))
|
||||
@@ -548,12 +750,27 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!XPCConvert::NativeData2JS(cx, &v, &dp->val, type,
|
||||
conditional_iid, &err))
|
||||
if(isArray)
|
||||
{
|
||||
ThrowBadParamException(err, cx, desc, i);
|
||||
goto done;
|
||||
if(!XPCConvert::NativeArray2JS(cx, &v, (const void**)&dp->val,
|
||||
type_in_array, conditional_iid,
|
||||
array_count, &err))
|
||||
{
|
||||
// XXX need exception scheme for arrays to indicate bad element
|
||||
ThrowBadParamException(err, cx, desc, i);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!XPCConvert::NativeData2JS(cx, &v, &dp->val, type,
|
||||
conditional_iid, &err))
|
||||
{
|
||||
ThrowBadParamException(err, cx, desc, i);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if(param.IsRetval())
|
||||
@@ -582,6 +799,10 @@ nsXPCWrappedNativeClass::CallWrappedMethod(JSContext* cx,
|
||||
retval = JS_TRUE;
|
||||
|
||||
done:
|
||||
// delete any array contents that have been allocated
|
||||
if(scavenger)
|
||||
delete scavenger;
|
||||
|
||||
// iterate through the params that were init'd (again!) and clean up
|
||||
// any alloc'd stuff and release wrappers of params
|
||||
for(i = 0; i < dispatchParamsInitedCount; i++)
|
||||
|
||||
@@ -442,6 +442,17 @@ MyEcho::MethodWithForwardDeclaredParam(nsITestXPCSomeUselessThing *sut)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void PseudoQueryInterface (in nsIIDRef uuid, [iid_is (uuid), retval] out nsQIResult result); */
|
||||
NS_IMETHODIMP
|
||||
MyEcho::PseudoQueryInterface(const nsIID & uuid, void * *result)
|
||||
{
|
||||
if(!result)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if(mReceiver)
|
||||
return mReceiver->PseudoQueryInterface(uuid, result);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
// security manager test class
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ LIBRARY_NAME = xpctest
|
||||
IS_COMPONENT = 1
|
||||
|
||||
CPPSRCS = \
|
||||
xpctest_array.cpp \
|
||||
xpctest_echo.cpp \
|
||||
xpctest_child.cpp \
|
||||
xpctest_noisy.cpp \
|
||||
|
||||
@@ -26,6 +26,7 @@ MODULE=xpconnect
|
||||
DEFINES=-DWIN32_LEAN_AND_MEAN
|
||||
|
||||
OBJS= \
|
||||
.\$(OBJDIR)\xpctest_array.obj \
|
||||
.\$(OBJDIR)\xpctest_echo.obj \
|
||||
.\$(OBJDIR)\xpctest_child.obj \
|
||||
.\$(OBJDIR)\xpctest_noisy.obj \
|
||||
|
||||
144
mozilla/js/src/xpconnect/tests/components/xpctest_array.cpp
Normal file
144
mozilla/js/src/xpconnect/tests/components/xpctest_array.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/* implement nsIXPCTestString for testing. */
|
||||
|
||||
#include "xpctest_private.h"
|
||||
|
||||
class xpcarraytest : public nsIXPCTestArray
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIXPCTESTARRAY
|
||||
|
||||
xpcarraytest();
|
||||
virtual ~xpcarraytest();
|
||||
};
|
||||
|
||||
xpcarraytest::xpcarraytest()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
NS_ADDREF_THIS();
|
||||
}
|
||||
|
||||
xpcarraytest::~xpcarraytest()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(xpcarraytest, nsIXPCTestArray);
|
||||
|
||||
/* void PrintIntegerArray (in PRUint32 count, [array, size_is (count)] in PRInt32 valueArray); */
|
||||
NS_IMETHODIMP
|
||||
xpcarraytest::PrintIntegerArray(PRUint32 count, PRInt32 *valueArray)
|
||||
{
|
||||
if(valueArray && count)
|
||||
{
|
||||
for(PRUint32 i = 0; i < count; i++)
|
||||
printf("%d%s", valueArray[i], i == count -1 ? "\n" : ",");
|
||||
}
|
||||
else
|
||||
printf("empty array\n");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void PrintStringArray (in PRUint32 count, [array, size_is (count)] in string valueArray); */
|
||||
NS_IMETHODIMP
|
||||
xpcarraytest::PrintStringArray(PRUint32 count, const char **valueArray)
|
||||
{
|
||||
if(valueArray && count)
|
||||
{
|
||||
for(PRUint32 i = 0; i < count; i++)
|
||||
printf("\"%s\"%s", valueArray[i], i == count -1 ? "\n" : ",");
|
||||
}
|
||||
else
|
||||
printf("empty array\n");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void MultiplyEachItemInIntegerArray (in PRInt32 val, in PRUint32 count, [array, size_is (count)] inout PRInt32 valueArray); */
|
||||
NS_IMETHODIMP
|
||||
xpcarraytest::MultiplyEachItemInIntegerArray(PRInt32 val, PRUint32 count, PRInt32 **valueArray)
|
||||
{
|
||||
PRInt32* a;
|
||||
if(valueArray && count && nsnull != (a = *valueArray))
|
||||
{
|
||||
for(PRUint32 i = 0; i < count; i++)
|
||||
a[i] *= val;
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* void MultiplyEachItemInIntegerArrayAndAppend (in PRInt32 val, inout PRUint32 count, [array, size_is (count)] inout PRInt32 valueArray); */
|
||||
NS_IMETHODIMP
|
||||
xpcarraytest::MultiplyEachItemInIntegerArrayAndAppend(PRInt32 val, PRUint32 *count, PRInt32 **valueArray)
|
||||
{
|
||||
PRInt32* in;
|
||||
PRUint32 in_count;
|
||||
if(valueArray && count && 0 != (in_count = *count) && nsnull != (in = *valueArray))
|
||||
{
|
||||
PRInt32* out =
|
||||
(PRInt32*) nsAllocator::Alloc(in_count * 2 * sizeof(PRUint32));
|
||||
|
||||
if(!out)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
for(PRUint32 i = 0; i < in_count; i++)
|
||||
{
|
||||
out[i*2] = in[i];
|
||||
out[i*2+1] = in[i] * val;
|
||||
}
|
||||
nsAllocator::Free(in);
|
||||
*valueArray = out;
|
||||
*count = in_count * 2;
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
// static
|
||||
NS_IMETHODIMP
|
||||
xpctest::ConstructArrayTest(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_ASSERTION(aOuter == nsnull, "no aggregation");
|
||||
xpcarraytest* obj = new xpcarraytest();
|
||||
|
||||
if(obj)
|
||||
{
|
||||
rv = obj->QueryInterface(aIID, aResult);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
|
||||
NS_RELEASE(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
*aResult = nsnull;
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -265,6 +265,17 @@ xpctestEcho::MethodWithForwardDeclaredParam(nsITestXPCSomeUselessThing *sut)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void PseudoQueryInterface (in nsIIDRef uuid, [iid_is (uuid), retval] out nsQIResult result); */
|
||||
NS_IMETHODIMP
|
||||
xpctestEcho::PseudoQueryInterface(const nsIID & uuid, void * *result)
|
||||
{
|
||||
if(!result)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if(mReceiver)
|
||||
return mReceiver->PseudoQueryInterface(uuid, result);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
// static
|
||||
|
||||
@@ -55,6 +55,8 @@ NSGetFactory(nsISupports* aServMgr,
|
||||
rv = factory->SetConstructor(xpctest::ConstructStringTest);
|
||||
else if(aClass.Equals(xpctest::GetOverloadedCID()))
|
||||
rv = factory->SetConstructor(xpctest::ConstructOverloaded);
|
||||
else if(aClass.Equals(xpctest::GetArrayTestCID()))
|
||||
rv = factory->SetConstructor(xpctest::ConstructArrayTest);
|
||||
else
|
||||
{
|
||||
NS_ASSERTION(0, "incorrectly registered");
|
||||
@@ -100,6 +102,9 @@ NSRegisterSelf(nsISupports* aServMgr , const char* aPath)
|
||||
"nsOverloaded", "nsOverloaded", aPath,
|
||||
PR_TRUE, PR_TRUE);
|
||||
|
||||
rv = compMgr->RegisterComponent(xpctest::GetArrayTestCID(),
|
||||
"nsArrayTest", "nsArrayTest", aPath,
|
||||
PR_TRUE, PR_TRUE);
|
||||
|
||||
return rv;
|
||||
}
|
||||
@@ -117,6 +122,7 @@ NSUnregisterSelf(nsISupports* aServMgr, const char* aPath)
|
||||
rv = compMgr->UnregisterComponent(xpctest::GetNoisyCID(), aPath);
|
||||
rv = compMgr->UnregisterComponent(xpctest::GetStringTestCID(), aPath);
|
||||
rv = compMgr->UnregisterComponent(xpctest::GetOverloadedCID(), aPath);
|
||||
rv = compMgr->UnregisterComponent(xpctest::GetArrayTestCID(), aPath);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,11 @@
|
||||
{ 0xdc5fde90, 0x439d, 0x11d3, \
|
||||
{ 0x98, 0x8c, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
|
||||
|
||||
// {5B9AF380-6569-11d3-989E-006008962422}
|
||||
#define NS_ARRAY_CID \
|
||||
{ 0x5b9af380, 0x6569, 0x11d3, \
|
||||
{ 0x98, 0x9e, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } };
|
||||
|
||||
|
||||
// 'namespace' class
|
||||
class xpctest
|
||||
@@ -80,6 +85,9 @@ public:
|
||||
static const nsID& GetOverloadedCID() {static nsID cid = NS_OVERLOADED_CID; return cid;}
|
||||
static NS_METHOD ConstructOverloaded(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
static const nsID& GetArrayTestCID() {static nsID cid = NS_ARRAY_CID; return cid;}
|
||||
static NS_METHOD ConstructArrayTest(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
private:
|
||||
xpctest(); // not implemented
|
||||
};
|
||||
|
||||
167
mozilla/js/src/xpconnect/tests/xpctest_exceptions.js
Normal file
167
mozilla/js/src/xpconnect/tests/xpctest_exceptions.js
Normal file
@@ -0,0 +1,167 @@
|
||||
|
||||
function printExceptionDoubleData(e) {
|
||||
if(!e || !e.data)
|
||||
return;
|
||||
if(e instanceof Components.interfaces.nsIXPCException) {
|
||||
try {
|
||||
var d = e.data.QueryInterface(Components.interfaces.nsISupportsDouble)
|
||||
try {
|
||||
print("e.data = "+d.data);
|
||||
} catch(i) {
|
||||
print("could not get double from e.data");
|
||||
|
||||
}
|
||||
} catch(i) {
|
||||
print("e.data was not an nsISupportsDouble");
|
||||
}
|
||||
}
|
||||
else {
|
||||
print("object was not an nsIXPCException");
|
||||
}
|
||||
}
|
||||
|
||||
var clazz = Components.classes.nsEcho;
|
||||
var iface = Components.interfaces.nsIEcho;
|
||||
var nativeEcho = clazz.createInstance(iface);
|
||||
|
||||
|
||||
var localEcho = {
|
||||
SendOneString : function() {throw this.result;},
|
||||
result : 0
|
||||
};
|
||||
|
||||
nativeEcho.SetReceiver(localEcho);
|
||||
|
||||
localEcho.result = 0;
|
||||
|
||||
print("\n");
|
||||
try {
|
||||
nativeEcho.SendOneString("foo");
|
||||
print("no error");
|
||||
} catch(e) {
|
||||
print("caught "+e);
|
||||
printExceptionDoubleData(e);
|
||||
}
|
||||
|
||||
localEcho.result = 1;
|
||||
|
||||
print("\n");
|
||||
try {
|
||||
nativeEcho.SendOneString("foo");
|
||||
print("no error");
|
||||
} catch(e) {
|
||||
print("caught "+e);
|
||||
printExceptionDoubleData(e);
|
||||
}
|
||||
|
||||
localEcho.result = -1;
|
||||
|
||||
print("\n");
|
||||
try {
|
||||
nativeEcho.SendOneString("foo");
|
||||
print("no error");
|
||||
} catch(e) {
|
||||
print("caught "+e);
|
||||
printExceptionDoubleData(e);
|
||||
}
|
||||
|
||||
localEcho.result = Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
print("\n");
|
||||
try {
|
||||
nativeEcho.SendOneString("foo");
|
||||
print("no error");
|
||||
} catch(e) {
|
||||
print("caught "+e);
|
||||
printExceptionDoubleData(e);
|
||||
}
|
||||
|
||||
localEcho.result = 0x80040154;
|
||||
|
||||
print("\n");
|
||||
try {
|
||||
nativeEcho.SendOneString("foo");
|
||||
print("no error");
|
||||
} catch(e) {
|
||||
print("caught "+e);
|
||||
printExceptionDoubleData(e);
|
||||
}
|
||||
|
||||
print("\n");
|
||||
localEcho.result = new Components.Exception("hi", Components.results.NS_ERROR_ABORT);
|
||||
try {
|
||||
nativeEcho.SendOneString("foo");
|
||||
|
||||
} catch(e) {
|
||||
print("caught "+e);
|
||||
}
|
||||
|
||||
print("\n");
|
||||
localEcho.result = {message : "pretending to be NS_OK does not work", result : 0};
|
||||
try {
|
||||
nativeEcho.SendOneString("foo");
|
||||
print("pretending 0 == NS_OK");
|
||||
} catch(e) {
|
||||
print("caught "+e);
|
||||
}
|
||||
|
||||
print("\n");
|
||||
localEcho.result = {message : "pretending to be NS_ERROR_NO_INTERFACE",
|
||||
result : Components.results.NS_ERROR_NO_INTERFACE};
|
||||
try {
|
||||
nativeEcho.SendOneString("foo");
|
||||
} catch(e) {
|
||||
print("caught "+e.message);
|
||||
}
|
||||
|
||||
print("\n");
|
||||
localEcho.result = "just a string";
|
||||
try {
|
||||
nativeEcho.SendOneString("foo");
|
||||
} catch(e) {
|
||||
print("caught "+e);
|
||||
}
|
||||
|
||||
print("\n");
|
||||
localEcho.result = Components.results.NS_ERROR_NO_INTERFACE;
|
||||
try {
|
||||
nativeEcho.SendOneString("foo");
|
||||
} catch(e) {
|
||||
print("caught "+e);
|
||||
}
|
||||
|
||||
print("\n");
|
||||
localEcho.result = "NS_OK";
|
||||
try {
|
||||
nativeEcho.SendOneString("foo");
|
||||
} catch(e) {
|
||||
print("caught "+e);
|
||||
}
|
||||
|
||||
print("\n");
|
||||
localEcho.result = Components;
|
||||
try {
|
||||
nativeEcho.SendOneString("foo");
|
||||
} catch(e) {
|
||||
print("caught "+e);
|
||||
}
|
||||
|
||||
print("\n");
|
||||
/* make this function have a JS runtime error */
|
||||
localEcho.SendOneString = function(){return Components.foo.bar;};
|
||||
try {
|
||||
nativeEcho.SendOneString("foo");
|
||||
} catch(e) {
|
||||
print("caught "+e);
|
||||
}
|
||||
|
||||
print("\n");
|
||||
/* make this function have a JS compiletime error */
|
||||
localEcho.SendOneString = function(){new Function("","foo ===== 1")};
|
||||
try {
|
||||
nativeEcho.SendOneString("foo");
|
||||
} catch(e) {
|
||||
print("caught "+e);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user