Bug 1444991 - Part 4: Handle DOM Objects in XPConnect, r=mccr8
authorNika Layzell <nika@thelayzells.com>
Fri, 06 Apr 2018 18:30:09 -0400
changeset 467736 667b0dbdc19019818ee3c42654ff18b2acaa36f6
parent 467735 ae4da56bcf71aeb41efdd4cd1a7a76d59cfcf1cc
child 467737 25b2e5c62dbf1c5ef699a6705fdcdd525fd35e64
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1444991
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1444991 - Part 4: Handle DOM Objects in XPConnect, r=mccr8 This patch goes through the XPConnect conversion methods, and adds cases for T_DOMOBJECT which call the Wrap, Unwrap, and Cleanup methods from the nsXPTDOMObjectInfo objects created in the last part. For consistency with normal interface pointers, and because it wasn't too complex, I also added support for including T_DOMOBJECTs in XPCOM arrays.
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCWrappedNative.cpp
xpcom/reflect/xptcall/xptcall.h
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -339,16 +339,27 @@ XPCConvert::NativeData2JS(MutableHandleV
             return XPCVariant::VariantDataToJS(variant,
                                                pErr, d);
         }
 
         xpcObjectHelper helper(iface);
         return NativeInterface2JSObject(d, helper, iid, true, pErr);
     }
 
+    case nsXPTType::T_DOMOBJECT:
+    {
+        void* ptr = *static_cast<void* const*>(s);
+        if (!ptr) {
+            d.setNull();
+            return true;
+        }
+
+        return type.GetDOMObjectInfo().Wrap(cx, ptr, d);
+    }
+
     default:
         NS_ERROR("bad type");
         return false;
     }
     return true;
 }
 
 /***************************************************************************/
@@ -700,16 +711,36 @@ XPCConvert::JSData2Native(void* d, Handl
             if (pErr && s.isInt32() && 0 == s.toInt32())
                 *pErr = NS_ERROR_XPC_BAD_CONVERT_JS_ZERO_ISNOT_NULL;
             return false;
         }
 
         RootedObject src(cx, &s.toObject());
         return JSObject2NativeInterface((void**)d, src, iid, nullptr, pErr);
     }
+
+    case nsXPTType::T_DOMOBJECT:
+    {
+        if (s.isNullOrUndefined()) {
+            *((void**)d) = nullptr;
+            return true;
+        }
+
+        // Can't handle non-JSObjects
+        if (!s.isObject()) {
+            return false;
+        }
+
+        nsresult err = type.GetDOMObjectInfo().Unwrap(s, (void**)d);
+        if (pErr) {
+            *pErr = err;
+        }
+        return NS_SUCCEEDED(err);
+    }
+
     default:
         NS_ERROR("bad type");
         return false;
     }
     return true;
 }
 
 /***************************************************************************/
@@ -1256,16 +1287,17 @@ XPCConvert::NativeArray2JS(MutableHandle
     case nsXPTType::T_WCHAR         : POPULATE(char16_t);       break;
     case nsXPTType::T_VOID          : NS_ERROR("bad type");     return false;
     case nsXPTType::T_IID           : POPULATE(nsID*);          break;
     case nsXPTType::T_DOMSTRING     : NS_ERROR("bad type");     return false;
     case nsXPTType::T_CHAR_STR      : POPULATE(char*);          break;
     case nsXPTType::T_WCHAR_STR     : POPULATE(char16_t*);      break;
     case nsXPTType::T_INTERFACE     : POPULATE(nsISupports*);   break;
     case nsXPTType::T_INTERFACE_IS  : POPULATE(nsISupports*);   break;
+    case nsXPTType::T_DOMOBJECT     : POPULATE(void*);          break;
     case nsXPTType::T_UTF8STRING    : NS_ERROR("bad type");     return false;
     case nsXPTType::T_CSTRING       : NS_ERROR("bad type");     return false;
     case nsXPTType::T_ASTRING       : NS_ERROR("bad type");     return false;
     default                         : NS_ERROR("bad type");     return false;
     }
 
     if (pErr)
         *pErr = NS_OK;
@@ -1520,18 +1552,18 @@ XPCConvert::JSArray2Native(void** d, Han
         for (initedCount = 0; initedCount < count; initedCount++) {            \
             if (!JS_GetElement(cx, jsarray, initedCount, &current) ||          \
                 !JSData2Native(((_t*)array)+initedCount, current, type,        \
                                iid, pErr))                                     \
                 goto failure;                                                  \
         }                                                                      \
     PR_END_MACRO
 
-    // No Action, FRee memory, RElease object
-    enum CleanupMode {na, fr, re};
+    // No Action, FRee memory, RElease object, CLeanup object
+    enum CleanupMode {na, fr, re, cl};
 
     CleanupMode cleanupMode;
 
     void* array = nullptr;
     uint32_t initedCount;
     RootedValue current(cx);
 
     // XXX check IsPtr - esp. to handle array of nsID (as opposed to nsID*)
@@ -1553,16 +1585,17 @@ XPCConvert::JSArray2Native(void** d, Han
     case nsXPTType::T_WCHAR         : POPULATE(na, char16_t);       break;
     case nsXPTType::T_VOID          : NS_ERROR("bad type");         goto failure;
     case nsXPTType::T_IID           : POPULATE(fr, nsID*);          break;
     case nsXPTType::T_DOMSTRING     : NS_ERROR("bad type");         goto failure;
     case nsXPTType::T_CHAR_STR      : POPULATE(fr, char*);          break;
     case nsXPTType::T_WCHAR_STR     : POPULATE(fr, char16_t*);      break;
     case nsXPTType::T_INTERFACE     : POPULATE(re, nsISupports*);   break;
     case nsXPTType::T_INTERFACE_IS  : POPULATE(re, nsISupports*);   break;
+    case nsXPTType::T_DOMOBJECT     : POPULATE(cl, void*);          break;
     case nsXPTType::T_UTF8STRING    : NS_ERROR("bad type");         goto failure;
     case nsXPTType::T_CSTRING       : NS_ERROR("bad type");         goto failure;
     case nsXPTType::T_ASTRING       : NS_ERROR("bad type");         goto failure;
     default                         : NS_ERROR("bad type");         goto failure;
     }
 
     *d = array;
     if (pErr)
@@ -1579,16 +1612,22 @@ failure:
                 NS_IF_RELEASE(p);
             }
         } else if (cleanupMode == fr) {
             void** a = (void**) array;
             for (uint32_t i = 0; i < initedCount; i++) {
                 void* p = a[i];
                 if (p) free(p);
             }
+        } else if (cleanupMode == cl) {
+            void** a = (void**) array;
+            for (uint32_t i = 0; i < initedCount; i++) {
+                void* p = a[i];
+                if (p) type.GetDOMObjectInfo().Cleanup(p);
+            }
         }
         free(array);
     }
 
     return false;
 
 #undef POPULATE
 }
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -1890,16 +1890,19 @@ CallMethodHelper::CleanupParam(nsXPTCMin
     switch (type.TagPart()) {
         case nsXPTType::T_JSVAL:
             js::RemoveRawValueRoot(mCallContext, (Value*)&param.val);
             break;
         case nsXPTType::T_INTERFACE:
         case nsXPTType::T_INTERFACE_IS:
             ((nsISupports*)param.val.p)->Release();
             break;
+        case nsXPTType::T_DOMOBJECT:
+            type.GetDOMObjectInfo().Cleanup(param.val.p);
+            break;
         case nsXPTType::T_ASTRING:
         case nsXPTType::T_DOMSTRING:
             mCallContext.GetContext()->mScratchStrings.Destroy((nsString*)param.val.p);
             break;
         case nsXPTType::T_UTF8STRING:
         case nsXPTType::T_CSTRING:
             mCallContext.GetContext()->mScratchCStrings.Destroy((nsCString*)param.val.p);
             break;
--- a/xpcom/reflect/xptcall/xptcall.h
+++ b/xpcom/reflect/xptcall/xptcall.h
@@ -123,16 +123,17 @@ struct nsXPTCVariant : public nsXPTCMini
               case nsXPTType::T_WCHAR:             val.wc  = mv.val.wc;  break;
               case nsXPTType::T_VOID:              /* fall through */
               case nsXPTType::T_IID:               /* fall through */
               case nsXPTType::T_DOMSTRING:         /* fall through */
               case nsXPTType::T_CHAR_STR:          /* fall through */
               case nsXPTType::T_WCHAR_STR:         /* fall through */
               case nsXPTType::T_INTERFACE:         /* fall through */
               case nsXPTType::T_INTERFACE_IS:      /* fall through */
+              case nsXPTType::T_DOMOBJECT:         /* fall through */
               case nsXPTType::T_ARRAY:             /* fall through */
               case nsXPTType::T_PSTRING_SIZE_IS:   /* fall through */
               case nsXPTType::T_PWSTRING_SIZE_IS:  /* fall through */
               case nsXPTType::T_UTF8STRING:        /* fall through */
               case nsXPTType::T_CSTRING:           /* fall through */
               default:                             val.p   = mv.val.p;   break;
             }
         }