Bug 956455, part 1 - WrapNative's holder argument is unnecessary. r=smaug
authorAndrew McCreight <continuation@gmail.com>
Mon, 06 Jan 2014 11:54:43 -0800
changeset 179281 2b139d0427aaf6b7d5964a604910e5f589558963
parent 179280 d322f50268deb68dbfc03c5a5a717a01a71b42c6
child 179282 5d406909e1325dad41d58e9b23e6fbdcd7c38d3a
push id462
push userraliiev@mozilla.com
push dateTue, 22 Apr 2014 00:22:30 +0000
treeherdermozilla-release@ac5db8c74ac0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs956455
milestone29.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 956455, part 1 - WrapNative's holder argument is unnecessary. r=smaug
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
content/base/src/nsDocument.cpp
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsXMLHttpRequest.cpp
content/xbl/src/nsXBLProtoImplMethod.cpp
content/xbl/src/nsXBLPrototypeHandler.cpp
content/xul/templates/src/nsXULTemplateBuilder.cpp
dom/base/MessagePort.cpp
dom/base/Navigator.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
js/xpconnect/public/nsTArrayHelpers.h
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -81,17 +81,16 @@ class nsIScriptGlobalObject;
 class nsIScriptSecurityManager;
 class nsIStringBundle;
 class nsIStringBundleService;
 class nsISupportsHashKey;
 class nsIURI;
 class nsIWidget;
 class nsIWordBreaker;
 class nsIXPConnect;
-class nsIXPConnectJSObjectHolder;
 class nsNodeInfoManager;
 class nsPIDOMWindow;
 class nsPresContext;
 class nsScriptObjectTracer;
 class nsStringBuffer;
 class nsStringHashKey;
 class nsTextFragment;
 class nsViewportInfo;
@@ -1636,46 +1635,34 @@ public:
    * If there is no JS in the stack or privileged JS is running, this
    * method returns true, otherwise false.
    */
   static bool CanAccessNativeAnon();
 
   static nsresult WrapNative(JSContext *cx, JS::Handle<JSObject*> scope,
                              nsISupports *native, const nsIID* aIID,
                              JS::MutableHandle<JS::Value> vp,
-                             // If non-null aHolder will keep the Value alive
-                             // while there's a ref to it
-                             nsIXPConnectJSObjectHolder** aHolder = nullptr,
                              bool aAllowWrapping = false)
   {
-    return WrapNative(cx, scope, native, nullptr, aIID, vp, aHolder,
-                      aAllowWrapping);
+    return WrapNative(cx, scope, native, nullptr, aIID, vp, aAllowWrapping);
   }
 
   // Same as the WrapNative above, but use this one if aIID is nsISupports' IID.
   static nsresult WrapNative(JSContext *cx, JS::Handle<JSObject*> scope,
                              nsISupports *native, JS::MutableHandle<JS::Value> vp,
-                             // If non-null aHolder will keep the Value alive
-                             // while there's a ref to it
-                             nsIXPConnectJSObjectHolder** aHolder = nullptr,
                              bool aAllowWrapping = false)
   {
-    return WrapNative(cx, scope, native, nullptr, nullptr, vp, aHolder,
-                      aAllowWrapping);
+    return WrapNative(cx, scope, native, nullptr, nullptr, vp, aAllowWrapping);
   }
   static nsresult WrapNative(JSContext *cx, JS::Handle<JSObject*> scope,
                              nsISupports *native, nsWrapperCache *cache,
                              JS::MutableHandle<JS::Value> vp,
-                             // If non-null aHolder will keep the Value alive
-                             // while there's a ref to it
-                             nsIXPConnectJSObjectHolder** aHolder = nullptr,
                              bool aAllowWrapping = false)
   {
-    return WrapNative(cx, scope, native, cache, nullptr, vp, aHolder,
-                      aAllowWrapping);
+    return WrapNative(cx, scope, native, cache, nullptr, vp, aAllowWrapping);
   }
 
   /**
    * Creates an arraybuffer from a binary string.
    */
   static nsresult CreateArrayBuffer(JSContext *aCx, const nsACString& aData,
                                     JSObject** aResult);
 
@@ -2128,17 +2115,16 @@ private:
   static nsresult EnsureStringBundle(PropertiesFile aFile);
 
   static bool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
                                 nsIPrincipal* aPrincipal);
 
   static nsresult WrapNative(JSContext *cx, JS::Handle<JSObject*> scope,
                              nsISupports *native, nsWrapperCache *cache,
                              const nsIID* aIID, JS::MutableHandle<JS::Value> vp,
-                             nsIXPConnectJSObjectHolder** aHolder,
                              bool aAllowWrapping);
 
   static nsresult DispatchEvent(nsIDocument* aDoc,
                                 nsISupports* aTarget,
                                 const nsAString& aEventName,
                                 bool aCanBubble,
                                 bool aCancelable,
                                 bool aTrusted,
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5608,22 +5608,19 @@ nsContentUtils::DispatchXULCommand(nsICo
   return target->DispatchEvent(event, &dummy);
 }
 
 // static
 nsresult
 nsContentUtils::WrapNative(JSContext *cx, JS::Handle<JSObject*> scope,
                            nsISupports *native, nsWrapperCache *cache,
                            const nsIID* aIID, JS::MutableHandle<JS::Value> vp,
-                           nsIXPConnectJSObjectHolder **aHolder,
                            bool aAllowWrapping)
 {
   if (!native) {
-    NS_ASSERTION(!aHolder || !*aHolder, "*aHolder should be null!");
-
     vp.setNull();
 
     return NS_OK;
   }
 
   JSObject *wrapper = xpc_FastGetCachedWrapper(cache, scope, vp);
   if (wrapper) {
     return NS_OK;
@@ -5633,17 +5630,17 @@ nsContentUtils::WrapNative(JSContext *cx
 
   if (!NS_IsMainThread()) {
     MOZ_CRASH();
   }
 
   nsresult rv = NS_OK;
   AutoPushJSContext context(cx);
   rv = sXPConnect->WrapNativeToJSVal(context, scope, native, cache, aIID,
-                                     aAllowWrapping, vp.address(), aHolder);
+                                     aAllowWrapping, vp.address(), nullptr);
   return rv;
 }
 
 nsresult
 nsContentUtils::CreateArrayBuffer(JSContext *aCx, const nsACString& aData,
                                   JSObject** aResult)
 {
   if (!aCx) {
@@ -5676,17 +5673,17 @@ nsContentUtils::CreateBlobBuffer(JSConte
   nsCOMPtr<nsIDOMBlob> blob;
   if (blobData) {
     memcpy(blobData, aData.BeginReading(), blobLen);
     blob = new nsDOMMemoryFile(blobData, blobLen, EmptyString());
   } else {
     return NS_ERROR_OUT_OF_MEMORY;
   }
   JS::Rooted<JSObject*> scope(aCx, JS::CurrentGlobalOrNull(aCx));
-  return nsContentUtils::WrapNative(aCx, scope, blob, aBlob, nullptr, true);
+  return nsContentUtils::WrapNative(aCx, scope, blob, aBlob, true);
 }
 
 void
 nsContentUtils::StripNullChars(const nsAString& aInStr, nsAString& aOutStr)
 {
   // In common cases where we don't have nulls in the
   // string we can simple simply bypass the checking code.
   int32_t firstNullPos = aInStr.FindChar('\0');
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -6800,17 +6800,17 @@ nsIDocument::AdoptNode(nsINode& aAdopted
       // We need to pass some sort of scope object to WrapNative. It's kind of
       // irrelevant, given that we're passing aAllowWrapping = false, and
       // documents should always insist on being wrapped in an canonical
       // scope. But we try to pass something sane anyway.
       JS::Rooted<JSObject*> global(cx, GetScopeObject()->GetGlobalJSObject());
 
       JS::Rooted<JS::Value> v(cx);
       rv = nsContentUtils::WrapNative(cx, global, this, this, &v,
-                                      nullptr, /* aAllowWrapping = */ false);
+                                      /* aAllowWrapping = */ false);
       if (rv.Failed())
         return nullptr;
       newScope = &v.toObject();
     }
   }
 
   nsCOMArray<nsINode> nodesWithProperties;
   rv = nsNodeUtils::Adopt(adoptedNode, sameDocument ? nullptr : mNodeInfoManager,
@@ -11464,21 +11464,19 @@ nsIDocument::WrapObject(JSContext *aCx, 
   if (this != win->GetExtantDoc()) {
     // We're not the current document; we're also done here
     return obj;
   }
 
   JSAutoCompartment ac(aCx, obj);
 
   JS::Rooted<JS::Value> winVal(aCx);
-  nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
   nsresult rv = nsContentUtils::WrapNative(aCx, obj, win,
                                            &NS_GET_IID(nsIDOMWindow),
                                            &winVal,
-                                           getter_AddRefs(holder),
                                            false);
   if (NS_FAILED(rv)) {
     Throw(aCx, rv);
     return nullptr;
   }
 
   NS_NAMED_LITERAL_STRING(doc_str, "document");
 
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -921,18 +921,17 @@ nsFrameMessageManager::ReceiveMessage(ns
 
       // The parameter for the listener function.
       JS::Rooted<JSObject*> param(ctx,
         JS_NewObject(ctx, nullptr, nullptr, nullptr));
       NS_ENSURE_TRUE(param, NS_ERROR_OUT_OF_MEMORY);
 
       JS::Rooted<JS::Value> targetv(ctx);
       JS::Rooted<JSObject*> global(ctx, JS_GetGlobalForObject(ctx, object));
-      nsContentUtils::WrapNative(ctx, global, aTarget, &targetv,
-                                 nullptr, true);
+      nsContentUtils::WrapNative(ctx, global, aTarget, &targetv, true);
 
       JS::Rooted<JSObject*> cpows(ctx);
       if (aCpows) {
         if (!aCpows->ToObject(ctx, &cpows)) {
           return NS_ERROR_UNEXPECTED;
         }
       }
 
@@ -1012,18 +1011,17 @@ nsFrameMessageManager::ReceiveMessage(ns
         // messageManager is wrapped in TabChildGlobal.
         nsCOMPtr<nsISupports> defaultThisValue;
         if (mChrome) {
           defaultThisValue = do_QueryObject(this);
         } else {
           defaultThisValue = aTarget;
         }
         JS::Rooted<JSObject*> global(ctx, JS_GetGlobalForObject(ctx, object));
-        nsContentUtils::WrapNative(ctx, global, defaultThisValue,
-                                   &thisValue, nullptr, true);
+        nsContentUtils::WrapNative(ctx, global, defaultThisValue, &thisValue, true);
       } else {
         // If the listener is a JS object which has receiveMessage function:
         if (!JS_GetProperty(ctx, object, "receiveMessage", &funval) ||
             !funval.isObject())
           return NS_ERROR_UNEXPECTED;
 
         // Check if the object is even callable.
         NS_ENSURE_STATE(JS_ObjectIsCallable(ctx, &funval.toObject()));
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -985,29 +985,29 @@ nsXMLHttpRequest::GetResponse(JSContext*
 
     if (!mResponseBlob) {
       return JSVAL_NULL;
     }
 
     JS::Rooted<JS::Value> result(aCx, JSVAL_NULL);
     JS::Rooted<JSObject*> scope(aCx, JS::CurrentGlobalOrNull(aCx));
     aRv = nsContentUtils::WrapNative(aCx, scope, mResponseBlob, &result,
-                                     nullptr, true);
+                                     true);
     return result;
   }
   case XML_HTTP_RESPONSE_TYPE_DOCUMENT:
   {
     if (!(mState & XML_HTTP_REQUEST_DONE) || !mResponseXML) {
       return JSVAL_NULL;
     }
 
     JS::Rooted<JSObject*> scope(aCx, JS::CurrentGlobalOrNull(aCx));
     JS::Rooted<JS::Value> result(aCx, JSVAL_NULL);
     aRv = nsContentUtils::WrapNative(aCx, scope, mResponseXML, &result,
-                                     nullptr, true);
+                                     true);
     return result;
   }
   case XML_HTTP_RESPONSE_TYPE_JSON:
   {
     if (!(mState & XML_HTTP_REQUEST_DONE)) {
       return JSVAL_NULL;
     }
 
--- a/content/xbl/src/nsXBLProtoImplMethod.cpp
+++ b/content/xbl/src/nsXBLProtoImplMethod.cpp
@@ -290,21 +290,19 @@ nsXBLProtoImplAnonymousMethod::Execute(n
   }
 
   nsAutoMicroTask mt;
 
   AutoPushJSContext cx(context->GetNativeContext());
 
   JS::Rooted<JSObject*> globalObject(cx, global->GetGlobalJSObject());
 
-  nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
   JS::Rooted<JS::Value> v(cx);
-  nsresult rv =
-    nsContentUtils::WrapNative(cx, globalObject, aBoundElement, &v,
-                               getter_AddRefs(wrapper));
+  nsresult rv = nsContentUtils::WrapNative(cx, globalObject, aBoundElement, &v);
+
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Use nsCxPusher to make sure we call ScriptEvaluated when we're done.
   //
   // Make sure to do this before entering the compartment, since pushing Push()
   // may call JS_SaveFrameChain(), which puts us back in an unentered state.
   nsCxPusher pusher;
   if (!pusher.Push(aBoundElement))
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -302,17 +302,17 @@ nsXBLPrototypeHandler::ExecuteHandler(Ev
   bool ok = JS_WrapObject(cx, &genericHandler);
   NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
   MOZ_ASSERT(!js::IsCrossCompartmentWrapper(genericHandler));
 
   // Wrap the native into the XBL scope. This creates a reflector in the document
   // scope if one doesn't already exist, and potentially wraps it cross-
   // compartment into our scope (via aAllowWrapping=true).
   JS::Rooted<JS::Value> targetV(cx, JS::UndefinedValue());
-  rv = nsContentUtils::WrapNative(cx, scopeObject, scriptTarget, &targetV, nullptr,
+  rv = nsContentUtils::WrapNative(cx, scopeObject, scriptTarget, &targetV,
                                   /* aAllowWrapping = */ true);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Next, clone the generic handler to be parented to the target.
   JS::Rooted<JSObject*> bound(cx, JS_CloneFunctionObject(cx, genericHandler, &targetV.toObject()));
   NS_ENSURE_TRUE(bound, NS_ERROR_FAILURE);
 
   // Now, wrap the bound handler into the content compartment and use it.
--- a/content/xul/templates/src/nsXULTemplateBuilder.cpp
+++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp
@@ -1385,46 +1385,43 @@ nsXULTemplateBuilder::InitHTMLTemplateRo
 
     AutoPushJSContext jscontext(context->GetNativeContext());
     NS_ASSERTION(context != nullptr, "no jscontext");
     if (! jscontext)
         return NS_ERROR_UNEXPECTED;
 
     JS::Rooted<JSObject*> scope(jscontext, global->GetGlobalJSObject());
     JS::Rooted<JS::Value> v(jscontext);
-    nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
-    rv = nsContentUtils::WrapNative(jscontext, scope, mRoot, mRoot, &v,
-                                    getter_AddRefs(wrapper));
+    rv = nsContentUtils::WrapNative(jscontext, scope, mRoot, mRoot, &v);
     NS_ENSURE_SUCCESS(rv, rv);
 
     JS::Rooted<JSObject*> jselement(jscontext, JSVAL_TO_OBJECT(v));
 
     if (mDB) {
         // database
         JS::Rooted<JS::Value> jsdatabase(jscontext);
         rv = nsContentUtils::WrapNative(jscontext, scope, mDB,
                                         &NS_GET_IID(nsIRDFCompositeDataSource),
-                                        &jsdatabase, getter_AddRefs(wrapper));
+                                        &jsdatabase);
         NS_ENSURE_SUCCESS(rv, rv);
 
         bool ok;
         ok = JS_SetProperty(jscontext, jselement, "database", jsdatabase);
         NS_ASSERTION(ok, "unable to set database property");
         if (! ok)
             return NS_ERROR_FAILURE;
     }
 
     {
         // builder
         JS::Rooted<JS::Value> jsbuilder(jscontext);
-        nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
         rv = nsContentUtils::WrapNative(jscontext, jselement,
                                         static_cast<nsIXULTemplateBuilder*>(this),
                                         &NS_GET_IID(nsIXULTemplateBuilder),
-                                        &jsbuilder, getter_AddRefs(wrapper));
+                                        &jsbuilder);
         NS_ENSURE_SUCCESS(rv, rv);
 
         bool ok;
         ok = JS_SetProperty(jscontext, jselement, "builder", jsbuilder);
         if (! ok)
             return NS_ERROR_FAILURE;
     }
 
--- a/dom/base/MessagePort.cpp
+++ b/dom/base/MessagePort.cpp
@@ -116,20 +116,18 @@ PostMessageReadStructuredClone(JSContext
   if (tag == SCTAG_DOM_BLOB || tag == SCTAG_DOM_FILELIST) {
     NS_ASSERTION(!data, "Data should be empty");
 
     nsISupports* supports;
     if (JS_ReadBytes(reader, &supports, sizeof(supports))) {
       JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
       if (global) {
         JS::Rooted<JS::Value> val(cx);
-        nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
         if (NS_SUCCEEDED(nsContentUtils::WrapNative(cx, global, supports,
-                                                    &val,
-                                                    getter_AddRefs(wrapper)))) {
+                                                    &val))) {
           return JSVAL_TO_OBJECT(val);
         }
       }
     }
   }
 
   if (tag == SCTAG_DOM_MESSAGEPORT) {
     NS_ASSERTION(!data, "Data should be empty");
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -1581,19 +1581,17 @@ Navigator::DoNewResolve(JSContext* aCx, 
 
     rv = gpi->Init(mWindow, prop_val.address());
     if (NS_FAILED(rv)) {
       return Throw(aCx, rv);
     }
   }
 
   if (JSVAL_IS_PRIMITIVE(prop_val) && !JSVAL_IS_NULL(prop_val)) {
-    nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
-    rv = nsContentUtils::WrapNative(aCx, aObject, native, &prop_val,
-                                    getter_AddRefs(holder), true);
+    rv = nsContentUtils::WrapNative(aCx, aObject, native, &prop_val, true);
 
     if (NS_FAILED(rv)) {
       return Throw(aCx, rv);
     }
   }
 
   if (!JS_WrapValue(aCx, &prop_val)) {
     return Throw(aCx, NS_ERROR_UNEXPECTED);
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -7548,20 +7548,18 @@ PostMessageReadStructuredClone(JSContext
   if (tag == SCTAG_DOM_BLOB || tag == SCTAG_DOM_FILELIST) {
     NS_ASSERTION(!data, "Data should be empty");
 
     nsISupports* supports;
     if (JS_ReadBytes(reader, &supports, sizeof(supports))) {
       JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
       if (global) {
         JS::Rooted<JS::Value> val(cx);
-        nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
         if (NS_SUCCEEDED(nsContentUtils::WrapNative(cx, global, supports,
-                                                    &val,
-                                                    getter_AddRefs(wrapper)))) {
+                                                    &val))) {
           return val.toObjectOrNull();
         }
       }
     }
   }
 
   if (MessageChannel::PrefEnabled() && tag == SCTAG_DOM_MESSAGEPORT) {
     NS_ASSERTION(!data, "Data should be empty");
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1267,20 +1267,18 @@ nsJSContext::ConvertSupportsTojsvals(nsI
           // just wrap it.
 #ifdef DEBUG
           // but first, check its not another nsISupportsPrimitive, as
           // these are now deprecated for use with script contexts.
           nsCOMPtr<nsISupportsPrimitive> prim(do_QueryInterface(arg));
           NS_ASSERTION(prim == nullptr,
                        "Don't pass nsISupportsPrimitives - use nsIVariant!");
 #endif
-          nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
           JS::Rooted<JS::Value> v(cx);
-          rv = nsContentUtils::WrapNative(cx, aScope, arg, &v,
-                                          getter_AddRefs(wrapper));
+          rv = nsContentUtils::WrapNative(cx, aScope, arg, &v);
           if (NS_SUCCEEDED(rv)) {
             *thisval = v;
           }
         }
       }
     }
   } else {
     nsCOMPtr<nsIVariant> variant = do_QueryInterface(aArgs);
@@ -1465,22 +1463,20 @@ nsJSContext::AddSupportsPrimitiveTojsval
       nsIID *iid = nullptr;
 
       p->GetData(getter_AddRefs(data));
       p->GetDataIID(&iid);
       NS_ENSURE_TRUE(iid, NS_ERROR_UNEXPECTED);
 
       AutoFree iidGuard(iid); // Free iid upon destruction.
 
-      nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
       JS::Rooted<JSObject*> global(cx, GetWindowProxy());
       JS::Rooted<JS::Value> v(cx);
       nsresult rv = nsContentUtils::WrapNative(cx, global,
-                                               data, iid, &v,
-                                               getter_AddRefs(wrapper));
+                                               data, iid, &v);
       NS_ENSURE_SUCCESS(rv, rv);
 
       *aArgv = v;
 
       break;
     }
     case nsISupportsPrimitive::TYPE_ID :
     case nsISupportsPrimitive::TYPE_PRUINT64 :
--- a/js/xpconnect/public/nsTArrayHelpers.h
+++ b/js/xpconnect/public/nsTArrayHelpers.h
@@ -27,18 +27,17 @@ nsTArrayToJSArray(JSContext* aCx, const 
   MOZ_ASSERT(global);
 
   for (uint32_t index = 0; index < aSourceArray.Length(); index++) {
     nsCOMPtr<nsISupports> obj;
     nsresult rv = aSourceArray[index]->QueryInterface(NS_GET_IID(nsISupports), getter_AddRefs(obj));
     NS_ENSURE_SUCCESS(rv, rv);
 
     JS::RootedValue wrappedVal(aCx);
-    rv = nsContentUtils::WrapNative(aCx, global, obj, &wrappedVal,
-                                    nullptr, true);
+    rv = nsContentUtils::WrapNative(aCx, global, obj, &wrappedVal, true);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (!JS_SetElement(aCx, arrayObj, index, &wrappedVal)) {
       NS_WARNING("JS_SetElement failed!");
       return NS_ERROR_FAILURE;
     }
   }