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 103681 04d13cf166ab1c0c6d765ff22551c0cee9199c44
parent 103680 054229ba8fd6663cb192f7663dd374146f30bc45
child 103682 e6cc3b189dcf840566d6b8f7f7930a741744b7fe
push id14110
push userryanvm@gmail.com
push dateTue, 28 Aug 2012 17:23:53 +0000
treeherdermozilla-inbound@04d13cf166ab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs785828
milestone18.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 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);
 }