Bug 785828 - Load libxul.so lazily in OS.Shared. r=froydnj
authorDavid Rajchenbach-Teller <dteller@mozilla.com>
Tue, 28 Aug 2012 13:23:47 -0400
changeset 105720 04d13cf166ab1c0c6d765ff22551c0cee9199c44
parent 105719 054229ba8fd6663cb192f7663dd374146f30bc45
child 105721 e6cc3b189dcf840566d6b8f7f7930a741744b7fe
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersfroydnj
bugs785828
milestone18.0a1
Bug 785828 - Load libxul.so lazily in OS.Shared. r=froydnj
toolkit/components/osfile/osfile_shared_allthreads.jsm
--- a/toolkit/components/osfile/osfile_shared_allthreads.jsm
+++ b/toolkit/components/osfile/osfile_shared_allthreads.jsm
@@ -26,16 +26,30 @@
      // Import components after having initialized |exports.OS|, to ensure
      // that everybody uses the same definition of |OS|.
      if (typeof Components != "undefined") {
        Components.utils.import("resource://gre/modules/ctypes.jsm");
        Components.classes["@mozilla.org/net/osfileconstantsservice;1"].
          getService(Components.interfaces.nsIOSFileConstantsService).init();
      }
 
+     // Define a lazy getter for a property
+     let defineLazyGetter = function(object, name, getter) {
+       Object.defineProperty(object, name, {
+         configurable: true,
+         get: function lazy() {
+           delete this[name];
+           let value = getter.call(this);
+           Object.defineProperty(object, name, {
+             value: value
+           });
+           return value;
+         }
+       });
+     };
 
      let LOG;
      if (typeof console != "undefined" && console.log) {
        LOG = console.log.bind(console, "OS");
      } else {
        LOG = function() {
          let text = "OS";
          for (let i = 0; i < arguments.length; ++i) {
@@ -793,18 +807,21 @@
      };
      exports.OS.Shared.declareFFI = declareFFI;
 
 
      /**
       * Libxul-based utilities, shared by all back-ends.
       */
 
-     let libxul = ctypes.open(OS.Constants.Path.libxul);
-     exports.OS.Shared.libxul = libxul;
+     // Lazy getter for libxul
+     defineLazyGetter(exports.OS.Shared, "libxul",
+       function init_libxul() {
+         return ctypes.open(OS.Constants.Path.libxul);
+       });
 
      exports.OS.Shared.Utils = {};
 
      let Strings = exports.OS.Shared.Utils.Strings = {};
 
      // A bogus array type used to perform pointer arithmetics
      let gOffsetByType;
 
@@ -856,54 +873,66 @@
       * (can be jschar* or a jschar[]).
       * @return {string} The same string, as a JavaScript String.
       */
      Strings.importWString = function importWString(wstring) {
        return wstring.readString();
      };
 
 
-     let NS_Free = libxul.declare("osfile_ns_free", ctypes.default_abi,
-       /*return*/ Types.void_t.implementation,
-       /*ptr*/ Types.voidptr_t.implementation);
-
-     let wstrdup = declareFFI(libxul, "osfile_wstrdup", ctypes.default_abi,
-       /*return*/ Types.out_wstring.releaseWith(NS_Free),
-       /*ptr*/ Types.wstring);
-
+     let Pointers = {};
+     defineLazyGetter(Pointers, "NS_Free",
+       function init_NS_Free() {
+         return exports.OS.Shared.libxul.declare("osfile_ns_free",
+           ctypes.default_abi,
+          /*return*/ Types.void_t.implementation,
+          /*ptr*/ Types.voidptr_t.implementation);
+       });
 
-      /**
-        * Export a string as a wide string (e.g. a |jschar.ptr|).
-        *
-        * @param {string} string A JavaScript String.
-        * @return {CData} The C representation of that string, as a |jschar*|.
-        * This value will be automatically garbage-collected once it is
-        * not referenced anymore.
-        */
-      Strings.exportWString = function exportWString(string) {
-        return wstrdup(string);
-      };
+     /**
+      * Export a string as a wide string (e.g. a |jschar.ptr|).
+      *
+      * @param {string} string A JavaScript String.
+      * @return {CData} The C representation of that string, as a |jschar*|.
+      * This value will be automatically garbage-collected once it is
+      * not referenced anymore.
+      */
+     defineLazyGetter(Strings, "exportWString",
+       function init_exportWString() {
+         return declareFFI(exports.OS.Shared.libxul,
+           "osfile_wstrdup",
+           ctypes.default_abi,
+           /*return*/ Types.out_wstring.releaseWith(Pointers.NS_Free),
+           /*ptr*/ Types.wstring);
+       });
 
 // Encodings
 
-     Strings.encodeAll = declareFFI(libxul, "osfile_EncodeAll",
-        ctypes.default_abi,
-         /*return*/     Types.void_t.out_ptr.releaseWith(NS_Free),
-         /*encoding*/   Types.cstring,
-         /*source*/     Types.wstring,
-         /*bytes*/      Types.uint32_t.out_ptr);
+     defineLazyGetter(Strings, "encodeAll",
+       function init_encodeAll() {
+         return declareFFI(exports.OS.Shared.libxul,
+           "osfile_EncodeAll",
+           ctypes.default_abi,
+           /*return*/     Types.void_t.out_ptr.releaseWith(Pointers.NS_Free),
+           /*encoding*/   Types.cstring,
+           /*source*/     Types.wstring,
+           /*bytes*/      Types.uint32_t.out_ptr);
+       });
 
-     let _decodeAll = declareFFI(libxul, "osfile_DecodeAll",
-        ctypes.default_abi,
-         /*return*/     Types.out_wstring.releaseWith(NS_Free),
-         /*encoding*/   Types.cstring,
-         /*source*/     Types.void_t.in_ptr,
-         /*bytes*/      Types.uint32_t);
-
-     Strings.decodeAll = function decodeAll(encoding, source, bytes) {
-       let decoded = _decodeAll(encoding, source, bytes);
-       if (!decoded) {
-         return null;
-       }
-       return Strings.importWString(decoded);
-     };
+     defineLazyGetter(Strings, "decodeAll",
+       function init_decodeAll() {
+         let _decodeAll = declareFFI(exports.OS.Shared.libxul, "osfile_DecodeAll",
+           ctypes.default_abi,
+            /*return*/     Types.out_wstring.releaseWith(Pointers.NS_Free),
+            /*encoding*/   Types.cstring,
+            /*source*/     Types.void_t.in_ptr,
+            /*bytes*/      Types.uint32_t);
+         return function decodeAll(encoding, source, bytes) {
+           let decoded = _decodeAll(encoding, source, bytes);
+           if (!decoded) {
+             return null;
+           }
+           return Strings.importWString(decoded);
+          };
+        }
+     );
    })(this);
 }