xpcom/reflect/xptcall/public/xptcall.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/xpcom/reflect/xptcall/public/xptcall.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,186 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +/* Public declarations for xptcall. */
    1.10 +
    1.11 +#ifndef xptcall_h___
    1.12 +#define xptcall_h___
    1.13 +
    1.14 +#include "nscore.h"
    1.15 +#include "nsISupports.h"
    1.16 +#include "xpt_struct.h"
    1.17 +#include "xptinfo.h"
    1.18 +#include "js/Value.h"
    1.19 +
    1.20 +struct nsXPTCMiniVariant
    1.21 +{
    1.22 +// No ctors or dtors so that we can use arrays of these on the stack
    1.23 +// with no penalty.
    1.24 +    union
    1.25 +    {
    1.26 +        int8_t    i8;
    1.27 +        int16_t   i16;
    1.28 +        int32_t   i32;
    1.29 +        int64_t   i64;
    1.30 +        uint8_t   u8;
    1.31 +        uint16_t  u16;
    1.32 +        uint32_t  u32;
    1.33 +        uint64_t  u64;
    1.34 +        float     f;
    1.35 +        double    d;
    1.36 +        bool      b;
    1.37 +        char      c;
    1.38 +        char16_t wc;
    1.39 +        void*     p;
    1.40 +
    1.41 +        // Types below here are unknown to the assembly implementations, and
    1.42 +        // therefore _must_ be passed with indirect semantics. We put them in
    1.43 +        // the union here for type safety, so that we can avoid void* tricks.
    1.44 +        JS::Value j;
    1.45 +    } val;
    1.46 +};
    1.47 +
    1.48 +struct nsXPTCVariant : public nsXPTCMiniVariant
    1.49 +{
    1.50 +// No ctors or dtors so that we can use arrays of these on the stack
    1.51 +// with no penalty.
    1.52 +
    1.53 +    // inherits 'val' here
    1.54 +    void*     ptr;
    1.55 +    nsXPTType type;
    1.56 +    uint8_t   flags;
    1.57 +
    1.58 +    enum
    1.59 +    {
    1.60 +        //
    1.61 +        // Bitflag definitions
    1.62 +        //
    1.63 +
    1.64 +        // Indicates that ptr (above, and distinct from val.p) is the value that
    1.65 +        // should be passed on the stack.
    1.66 +        //
    1.67 +        // In theory, ptr could point anywhere. But in practice it always points
    1.68 +        // to &val. So this flag is used to pass 'val' by reference, letting us
    1.69 +        // avoid the extra allocation we would incur if we were to use val.p.
    1.70 +        //
    1.71 +        // Various parts of XPConnect assume that ptr==&val, so we enforce it
    1.72 +        // explicitly with SetIndirect() and IsIndirect().
    1.73 +        //
    1.74 +        // Since ptr always points to &val, the semantics of this flag are kind of
    1.75 +        // dumb, since the ptr field is unnecessary. But changing them would
    1.76 +        // require changing dozens of assembly files, so they're likely to stay
    1.77 +        // the way they are.
    1.78 +        PTR_IS_DATA    = 0x1,
    1.79 +
    1.80 +        // Indicates that the value we hold requires some sort of cleanup (memory
    1.81 +        // deallocation, interface release, JS::Value unrooting, etc). The precise
    1.82 +        // cleanup that is performed depends on the 'type' field above.
    1.83 +        // If the value is an array, this flag specifies whether the elements
    1.84 +        // within the array require cleanup (we always clean up the array itself,
    1.85 +        // so this flag would be redundant for that purpose).
    1.86 +        VAL_NEEDS_CLEANUP = 0x2
    1.87 +    };
    1.88 +
    1.89 +    void ClearFlags()         {flags = 0;}
    1.90 +    void SetIndirect()        {ptr = &val; flags |= PTR_IS_DATA;}
    1.91 +    void SetValNeedsCleanup() {flags |= VAL_NEEDS_CLEANUP;}
    1.92 +
    1.93 +    bool IsIndirect()         const  {return 0 != (flags & PTR_IS_DATA);}
    1.94 +    bool DoesValNeedCleanup() const  {return 0 != (flags & VAL_NEEDS_CLEANUP);}
    1.95 +
    1.96 +    // Internal use only. Use IsIndirect() instead.
    1.97 +    bool IsPtrData()       const  {return 0 != (flags & PTR_IS_DATA);}
    1.98 +
    1.99 +    void Init(const nsXPTCMiniVariant& mv, const nsXPTType& t, uint8_t f)
   1.100 +    {
   1.101 +        type = t;
   1.102 +        flags = f;
   1.103 +
   1.104 +        if(f & PTR_IS_DATA)
   1.105 +        {
   1.106 +            ptr = mv.val.p;
   1.107 +            val.p = nullptr;
   1.108 +        }
   1.109 +        else
   1.110 +        {
   1.111 +            ptr = nullptr;
   1.112 +            val.p = nullptr; // make sure 'val.p' is always initialized
   1.113 +            switch(t.TagPart()) {
   1.114 +              case nsXPTType::T_I8:                val.i8  = mv.val.i8;  break;
   1.115 +              case nsXPTType::T_I16:               val.i16 = mv.val.i16; break;
   1.116 +              case nsXPTType::T_I32:               val.i32 = mv.val.i32; break;
   1.117 +              case nsXPTType::T_I64:               val.i64 = mv.val.i64; break;
   1.118 +              case nsXPTType::T_U8:                val.u8  = mv.val.u8;  break;
   1.119 +              case nsXPTType::T_U16:               val.u16 = mv.val.u16; break;
   1.120 +              case nsXPTType::T_U32:               val.u32 = mv.val.u32; break;
   1.121 +              case nsXPTType::T_U64:               val.u64 = mv.val.u64; break;
   1.122 +              case nsXPTType::T_FLOAT:             val.f   = mv.val.f;   break;
   1.123 +              case nsXPTType::T_DOUBLE:            val.d   = mv.val.d;   break;
   1.124 +              case nsXPTType::T_BOOL:              val.b   = mv.val.b;   break;
   1.125 +              case nsXPTType::T_CHAR:              val.c   = mv.val.c;   break;
   1.126 +              case nsXPTType::T_WCHAR:             val.wc  = mv.val.wc;  break;
   1.127 +              case nsXPTType::T_VOID:              /* fall through */
   1.128 +              case nsXPTType::T_IID:               /* fall through */
   1.129 +              case nsXPTType::T_DOMSTRING:         /* fall through */
   1.130 +              case nsXPTType::T_CHAR_STR:          /* fall through */
   1.131 +              case nsXPTType::T_WCHAR_STR:         /* fall through */
   1.132 +              case nsXPTType::T_INTERFACE:         /* fall through */
   1.133 +              case nsXPTType::T_INTERFACE_IS:      /* fall through */
   1.134 +              case nsXPTType::T_ARRAY:             /* fall through */
   1.135 +              case nsXPTType::T_PSTRING_SIZE_IS:   /* fall through */
   1.136 +              case nsXPTType::T_PWSTRING_SIZE_IS:  /* fall through */
   1.137 +              case nsXPTType::T_UTF8STRING:        /* fall through */
   1.138 +              case nsXPTType::T_CSTRING:           /* fall through */              
   1.139 +              default:                             val.p   = mv.val.p;   break;
   1.140 +            }
   1.141 +        }
   1.142 +    }
   1.143 +};
   1.144 +
   1.145 +class nsIXPTCProxy : public nsISupports
   1.146 +{
   1.147 +public:
   1.148 +    NS_IMETHOD CallMethod(uint16_t aMethodIndex,
   1.149 +                          const XPTMethodDescriptor *aInfo,
   1.150 +                          nsXPTCMiniVariant *aParams) = 0;
   1.151 +};
   1.152 +
   1.153 +/**
   1.154 + * This is a typedef to avoid confusion between the canonical
   1.155 + * nsISupports* that provides object identity and an interface pointer
   1.156 + * for inheriting interfaces that aren't known at compile-time.
   1.157 + */
   1.158 +typedef nsISupports nsISomeInterface;
   1.159 +
   1.160 +/**
   1.161 + * Get a proxy object to implement the specified interface.
   1.162 + *
   1.163 + * @param aIID    The IID of the interface to implement.
   1.164 + * @param aOuter  An object to receive method calls from the proxy object.
   1.165 + *                The stub forwards QueryInterface/AddRef/Release to the
   1.166 + *                outer object. The proxy object does not hold a reference to
   1.167 + *                the outer object; it is the caller's responsibility to
   1.168 + *                ensure that this pointer remains valid until the stub has
   1.169 + *                been destroyed.
   1.170 + * @param aStub   Out parameter for the new proxy object. The object is
   1.171 + *                not addrefed. The object never destroys itself. It must be
   1.172 + *                explicitly destroyed by calling
   1.173 + *                NS_DestroyXPTCallStub when it is no longer needed.
   1.174 + */
   1.175 +XPCOM_API(nsresult)
   1.176 +NS_GetXPTCallStub(REFNSIID aIID, nsIXPTCProxy* aOuter,
   1.177 +                  nsISomeInterface* *aStub);
   1.178 +
   1.179 +/**
   1.180 + * Destroys an XPTCall stub previously created with NS_GetXPTCallStub.
   1.181 + */
   1.182 +XPCOM_API(void)
   1.183 +NS_DestroyXPTCallStub(nsISomeInterface* aStub);
   1.184 +
   1.185 +XPCOM_API(nsresult)
   1.186 +NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
   1.187 +                 uint32_t paramCount, nsXPTCVariant* params);
   1.188 +
   1.189 +#endif /* xptcall_h___ */

mercurial