Mercurial > JSWeakRef
changeset 0:7180966f48bf
Origination.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Thu, 16 Apr 2009 15:23:22 -0700 |
parents | |
children | 496cd9ab2298 |
files | JSWeakRef/chrome.manifest JSWeakRef/content/test.html JSWeakRef/install.rdf JSWeakRef/modules/memory_tracking.js JSWeakRef/platform/Darwin_x86-gcc3/components/JSWeakRef.xpt JSWeakRef/platform/Darwin_x86-gcc3/components/libJSWeakRef.dylib components/Makefile.in components/install.rdf components/public/Makefile.in components/public/nsIJSWeakRef.idl components/src/JSWeakRefModule.cpp components/src/Makefile.in components/src/nsJSWeakRef.cpp components/src/nsJSWeakRef.h get_xpcom_info.js manage.py |
diffstat | 16 files changed, 727 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/JSWeakRef/chrome.manifest Thu Apr 16 15:23:22 2009 -0700 @@ -0,0 +1,2 @@ +resource JSWeakRef ./ +content JSWeakRef content/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/JSWeakRef/content/test.html Thu Apr 16 15:23:22 2009 -0700 @@ -0,0 +1,23 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> + <title>Memory Tracker</title> +</head> +<body> +</body> +<script> +Components.utils.import("resource://JSWeakRef/modules/memory_tracking.js"); + +function showLiveObjects() { + var liveObjs = MemoryTracking.getLiveObjects(); + document.body.innerHTML = liveObjs.join("<br/>"); +} + +var blah = new Object(); +MemoryTracking.track(blah); + +window.setInterval(showLiveObjects, 250); +</script> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/JSWeakRef/install.rdf Thu Apr 16 15:23:22 2009 -0700 @@ -0,0 +1,26 @@ +<?xml version="1.0"?> + +<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:em="http://www.mozilla.org/2004/em-rdf#"> + <Description about="urn:mozilla:install-manifest"> + <em:id>JSWeakRef@labs.mozilla.com</em:id> + <em:version>0.1</em:version> + <em:type>2</em:type> + + <!-- Target Application this extension can install into, + with minimum and maximum supported versions. --> + <em:targetApplication> + <Description> + <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> + <em:minVersion>3.0</em:minVersion> + <em:maxVersion>3.0.9</em:maxVersion> + </Description> + </em:targetApplication> + + <!-- Front End MetaData --> + <em:name>JSWeakRef</em:name> + <em:description>Weak References in JavaScript.</em:description> + <em:creator>Mozilla Corporation</em:creator> + <em:homepageURL>http://wiki.mozilla.org/Labs/JSWeakRef</em:homepageURL> + </Description> +</RDF>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/JSWeakRef/modules/memory_tracking.js Thu Apr 16 15:23:22 2009 -0700 @@ -0,0 +1,75 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JSWeakRef. + * + * The Initial Developer of the Original Code is Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Atul Varma <atul@mozilla.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var EXPORTED_SYMBOLS = ["MemoryTracking"]; + +var classIds = {}; +var trackedItems = {}; + +var MemoryTracking = { + track: function track(obj, name) { + var weakref; + try { + weakref = Components.classes["@labs.mozilla.com/jsweakrefdi;1"] + .createInstance(Components.interfaces.nsIJSWeakRef); + } catch (e) { + // Weakrefs aren't available, do nothing. + return; + } + weakref.set(obj); + + var className = obj.constructor.name; + if (name) + className += "_" + name; + if (typeof(classIds[className]) == "undefined") + classIds[className] = 0; + var itemName = className + "_" + classIds[className]; + classIds[className]++; + trackedItems[itemName] = weakref; + }, + + getLiveObjects: function getLiveObjects() { + var liveObjects = []; + + for (name in trackedItems) { + if (trackedItems[name].get()) + liveObjects.push(name); + else + delete trackedItems[name]; + } + return liveObjects; + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/Makefile.in Thu Apr 16 15:23:22 2009 -0700 @@ -0,0 +1,16 @@ +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +DIRS = public src + +XPI_NAME = JSWeakRef-components +INSTALL_EXTENSION_ID = JSWeakRef-components@labs.mozilla.com +XPI_PKGNAME = JSWeakRef-components + +DIST_FILES = install.rdf + +include $(topsrcdir)/config/rules.mk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/install.rdf Thu Apr 16 15:23:22 2009 -0700 @@ -0,0 +1,29 @@ +<?xml version="1.0"?> + +<!-- This isn't the install.rdf for a 'real' extension; it's just + a placeholder so that the Mozilla build system will generate + an XPI that we can pull binary XPCOM components out of. --> + +<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:em="http://www.mozilla.org/2004/em-rdf#"> + <Description about="urn:mozilla:install-manifest"> + <em:id>JSWeakRef-components@labs.mozilla.com</em:id> + <em:version>0.1</em:version> + <em:type>2</em:type> + + <!-- Target Application this extension can install into, + with minimum and maximum supported versions. --> + <em:targetApplication> + <Description> + <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> + <em:minVersion>3.0</em:minVersion> + <em:maxVersion>3.0.9</em:maxVersion> + </Description> + </em:targetApplication> + + <!-- Front End MetaData --> + <em:name>JSWeakRef Components</em:name> + <em:description>Binary XPCOM components for JSWeakRef</em:description> + <em:creator>Mozilla Corporation</em:creator> + </Description> +</RDF>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/public/Makefile.in Thu Apr 16 15:23:22 2009 -0700 @@ -0,0 +1,16 @@ +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = JSWeakRef +XPIDL_MODULE = JSWeakRef + +XPI_NAME = JSWeakRef-components + +XPIDLSRCS = nsIJSWeakRef.idl \ + $(NULL) + +include $(topsrcdir)/config/rules.mk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/public/nsIJSWeakRef.idl Thu Apr 16 15:23:22 2009 -0700 @@ -0,0 +1,8 @@ +#include "nsISupports.idl" + +[scriptable, uuid(fc04ea60-17df-11de-8c30-0800200c9a66)] +interface nsIJSWeakRef : nsISupports +{ + void set(/* JSObject param */); + /* JSObject param */ void get(); +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/src/JSWeakRefModule.cpp Thu Apr 16 15:23:22 2009 -0700 @@ -0,0 +1,16 @@ +#include "nsIGenericFactory.h" +#include "nsJSWeakRef.h" + +NS_GENERIC_FACTORY_CONSTRUCTOR(nsJSWeakRef) + +static nsModuleComponentInfo components[] = +{ + { + NSJSWEAKREFDI_CLASSNAME, + NSJSWEAKREFDI_CID, + NSJSWEAKREFDI_CONTRACTID, + nsJSWeakRefConstructor, + } +}; + +NS_IMPL_NSGETMODULE("JSWeakRefModule", components)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/src/Makefile.in Thu Apr 16 15:23:22 2009 -0700 @@ -0,0 +1,39 @@ +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +IS_COMPONENT = 1 +MODULE = JSWeakRef +LIBRARY_NAME = JSWeakRef +USE_STATIC_LIBS = 1 +#FORCE_SHARED_LIB = 1 +#FORCE_USE_PIC = 1 + +XPI_NAME = JSWeakRef-components + +REQUIRES = \ + xpcom \ + string \ + js \ + xpconnect \ + caps \ + dom \ + $(NULL) + +CPPSRCS = nsJSWeakRef.cpp \ + JSWeakRefModule.cpp \ + $(NULL) + +include $(topsrcdir)/config/rules.mk + +EXTRA_DSO_LDOPTS += \ + $(MOZ_JS_LIBS) \ + $(XPCOM_GLUE_LDOPTS) \ + $(NSPR_LIBS) \ + $(NULL) + +clobber:: + rm -f $(DIST)/lib/$(LIBRARY_NAME).lib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/src/nsJSWeakRef.cpp Thu Apr 16 15:23:22 2009 -0700 @@ -0,0 +1,178 @@ +#include "nsJSWeakRef.h" + +#include "jsapi.h" +#include "nsIXPConnect.h" +#include "nsAXPCNativeCallContext.h" +#include "nsServiceManagerUtils.h" +#include "nsComponentManagerUtils.h" + +class nsJSWeakRefListNode { +public: + nsJSWeakRef *data; + nsJSWeakRefListNode *next; +}; + +class nsJSWeakRefImpl { +public: + JSObject *weakRef; + JSContext *weakCx; + nsJSWeakRefListNode *node; +}; + +static nsJSWeakRefListNode *gList; +static JSGCCallback gOldJSGCCallback; + +void processGarbage() { + nsJSWeakRefListNode *node = gList; + nsJSWeakRefListNode *prevNode = nsnull; + nsJSWeakRefListNode *nextNode = nsnull; + while (node) { + nextNode = node->next; + if (node->data) { + if (JS_IsAboutToBeFinalized(node->data->impl->weakCx, + node->data->impl->weakRef)) { + // Tell the weak reference holder that its target no longer exists. + node->data->impl->weakRef = nsnull; + node->data->impl->weakCx = nsnull; + node->data->impl->node = nsnull; + + // Delete this node. + if (prevNode) + prevNode->next = nextNode; + else + gList = nextNode; + delete node; + } else + // This is our general case; just move on to the next node. + prevNode = node; + } else { + // The weak reference holder went away, so just delete this node. + if (prevNode) + prevNode->next = nextNode; + else + gList = nextNode; + delete node; + } + node = nextNode; + } +} + +static JSBool XPCCycleCollectGCCallback(JSContext *cx, JSGCStatus status) { + if (status == JSGC_MARK_END) + processGarbage(); + return gOldJSGCCallback ? gOldJSGCCallback(cx, status) : JS_TRUE; +} + +nsJSWeakRef::nsJSWeakRef() +{ + this->impl = new nsJSWeakRefImpl(); + this->impl->weakRef = nsnull; + this->impl->weakCx = nsnull; + this->impl->node = nsnull; +} + +nsJSWeakRef::~nsJSWeakRef() +{ + if (this->impl->node) + // Tell the GC callback to remove our node from the list next time around. + this->impl->node->data = nsnull; + + delete this->impl; + this->impl = nsnull; +} + +NS_IMETHODIMP nsJSWeakRef::Set() +{ + nsresult rv = NS_OK; + nsCOMPtr<nsIXPConnect> xpc = do_GetService( + "@mozilla.org/js/xpc/XPConnect;1", + &rv + ); + if (NS_FAILED(rv)) + return NS_ERROR_FAILURE; + + // get the xpconnect native call context + nsAXPCNativeCallContext *cc = nsnull; + xpc->GetCurrentNativeCallContext(&cc); + if(!cc) + return NS_ERROR_FAILURE; + + // Get JSContext of current call + JSContext* cx; + rv = cc->GetJSContext(&cx); + if(NS_FAILED(rv) || !cx) + return NS_ERROR_FAILURE; + + // get place for return value + jsval *rval = nsnull; + rv = cc->GetRetValPtr(&rval); + if(NS_FAILED(rv) || !rval) + return NS_ERROR_FAILURE; + + // get argc and argv and verify arg count + PRUint32 argc; + rv = cc->GetArgc(&argc); + if(NS_FAILED(rv)) + return rv; + + if (argc < 1) + return NS_ERROR_XPC_NOT_ENOUGH_ARGS; + + jsval *argv; + rv = cc->GetArgvPtr(&argv); + if (NS_FAILED(rv)) + return rv; + + if (!JSVAL_IS_OBJECT(argv[0])) + return NS_ERROR_ILLEGAL_VALUE; + + this->impl->weakRef = JSVAL_TO_OBJECT(argv[0]); + this->impl->weakCx = cx; + + // Insert a new node at the head of the global list. + nsJSWeakRefListNode *newNode = new nsJSWeakRefListNode(); + newNode->data = this; + newNode->next = gList; + this->impl->node = newNode; + gList = newNode; + + // TODO: Note that this is never removed. + if (!gOldJSGCCallback) + gOldJSGCCallback = JS_SetGCCallback(cx, XPCCycleCollectGCCallback); + + return NS_OK; +} + +NS_IMETHODIMP nsJSWeakRef::Get() +{ + nsresult rv = NS_OK; + nsCOMPtr<nsIXPConnect> xpc = do_GetService( + "@mozilla.org/js/xpc/XPConnect;1", + &rv + ); + if (NS_FAILED(rv)) + return NS_ERROR_FAILURE; + + // get the xpconnect native call context + nsAXPCNativeCallContext *cc = nsnull; + xpc->GetCurrentNativeCallContext(&cc); + if(!cc) + return NS_ERROR_FAILURE; + + // get place for return value + jsval *rval = nsnull; + rv = cc->GetRetValPtr(&rval); + if(NS_FAILED(rv) || !rval) + return NS_ERROR_FAILURE; + + // TODO: Do we have to increase the reference count of the object + // or anything? + + // This automatically is set to JSVAL_NULL if weakRef is nsnull. + *rval = OBJECT_TO_JSVAL(this->impl->weakRef); + cc->SetReturnValueWasSet(PR_TRUE); + + return NS_OK; +} + +NS_IMPL_ISUPPORTS1(nsJSWeakRef, nsIJSWeakRef);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/src/nsJSWeakRef.h Thu Apr 16 15:23:22 2009 -0700 @@ -0,0 +1,28 @@ +#include "nsIJSWeakRef.h" + +#define NSJSWEAKREFDI_CONTRACTID "@labs.mozilla.com/jsweakrefdi;1" +#define NSJSWEAKREFDI_CLASSNAME "nsJSWeakRef" +#define NSJSWEAKREFDI_CID \ + {0x32665020, 0x17e1, 0x11de, \ + { 0x8c, 0x30, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 }} + +class nsJSWeakRefImpl; + +void processGarbage(); + +class nsJSWeakRef : public nsIJSWeakRef +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIJSWEAKREF + + nsJSWeakRef(); + +private: + virtual ~nsJSWeakRef(); + nsJSWeakRefImpl *impl; + friend void processGarbage(); + +protected: + /* additional members */ +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/get_xpcom_info.js Thu Apr 16 15:23:22 2009 -0700 @@ -0,0 +1,5 @@ +var xulr = Components.classes["@mozilla.org/xre/app-info;1"] + .getService(Components.interfaces.nsIXULRuntime); + +dump(xulr.OS + "\n"); +dump(xulr.XPCOMABI + "\n");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/manage.py Thu Apr 16 15:23:22 2009 -0700 @@ -0,0 +1,266 @@ +import os +import sys +import xml.dom.minidom +import subprocess +import shutil +import zipfile +import shutil +import distutils.dir_util +from ConfigParser import ConfigParser + +# Path to the root of the extension, relative to where this script is +# located. +EXT_SUBDIR = "JSWeakRef" + +# Full path to xpcshell; if it's not an absolute path, it's assumed +# to be on the user's PATH. +g_xpcshell_path = "xpcshell" + +g_mydir = os.path.abspath(os.path.split(__import__("__main__").__file__)[0]) + +def clear_dir(dirname): + if os.path.exists(dirname) and os.path.isdir(dirname): + shutil.rmtree(dirname) + +def find_profile_dir(name): + """ + Given the name of a Firefox profile, attempts to find the absolute + path to its directory. If it can't be found, None is returned. + """ + + base_path = None + if sys.platform == "darwin": + base_path = os.path.expanduser( + "~/Library/Application Support/Firefox/" + ) + elif sys.platform.startswith("win"): + # TODO: This only works on 2000/XP/Vista, not 98/Me. + appdata = os.environ["APPDATA"] + base_path = os.path.join(appdata, "Mozilla\\Firefox") + elif sys.platform == "cygwin": + appdata = os.environ["APPDATA"] + base_path = os.path.join(appdata, "Mozilla\\Firefox") + else: + base_path = os.path.expanduser("~/.mozilla/firefox/") + inifile = os.path.join(base_path, "profiles.ini") + config = ConfigParser() + config.read(inifile) + profiles = [section for section in config.sections() + if section.startswith("Profile")] + for profile in profiles: + if config.get(profile, "Name") == name: + # TODO: Look at IsRelative? + path = config.get(profile, "Path") + if not os.path.isabs(path): + path = os.path.join(base_path, path) + print "Found profile '%s' at %s." % (name, path) + return path + print "Couldn't find a profile called '%s'." % name + return None + +def get_install_rdf_dom(path_to_extension_root): + rdf_path = os.path.join(path_to_extension_root, "install.rdf") + rdf = xml.dom.minidom.parse(rdf_path) + return rdf + +def get_install_rdf_property(path_to_extension_root, property): + rdf = get_install_rdf_dom(path_to_extension_root) + element = rdf.documentElement.getElementsByTagName(property)[0] + return element.firstChild.nodeValue + +def run_program(args, **kwargs): + retval = subprocess.call(args, **kwargs) + if retval: + print "Process failed with exit code %d." % retval + sys.exit(retval) + +def run_python_script(args): + run_program([sys.executable] + args) + +def get_xpcom_info(): + cmdline = [ + os.path.join(os.path.dirname(g_xpcshell_path), + "run-mozilla.sh"), + g_xpcshell_path, + os.path.join(g_mydir, "get_xpcom_info.js") + ] + if not os.path.exists(cmdline[0]): + cmdline = cmdline[1:] + popen = subprocess.Popen( + cmdline, + stdout = subprocess.PIPE + ) + retval = popen.wait() + assert retval == 0 + os_target, xpcomabi = popen.stdout.read().splitlines() + comsd = os.path.join(os.path.dirname(g_xpcshell_path), + "components") + return dict(comsd = comsd, + os_target = os_target, + xpcomabi = xpcomabi) + +if __name__ == "__main__": + args = sys.argv[1:] + if not args: + print "usage: %s <command>" % sys.argv[0] + print + print "'command' can be one of the following:" + print + print " try - run Firefox w/ new profile and extension installed" + print " install - install to the given profile" + print " uninstall - uninstall from the given profile" + print " build-xpi - build an xpi of the addon" + print " build-components - build C++ XPCOM components" + print + sys.exit(1) + + if os.environ.get("OBJDIR"): + g_xpcshell_path = os.path.join(os.environ["OBJDIR"], + "dist", "bin", g_xpcshell_path) + + path_to_extension_root = os.path.join(g_mydir, EXT_SUBDIR) + + cmd = args[0] + + if cmd == "try": + import systemtests + import jsbridge + print ("Starting Firefox with a new profile and " + "the extension installed...") + moz = jsbridge.start_from_settings(systemtests.settings) + print "Firefox started, quit it or press CTRL-C to exit." + try: + moz.wait() + except KeyboardInterrupt: + moz.stop() + print "Farewell." + sys.exit(0) + if cmd in ["install", "uninstall"]: + if len(args) != 2: + print "Attempting to find location of default profile..." + + profile_dir = find_profile_dir("default") + else: + profile_dir = args[1] + if not os.path.exists(profile_dir): + print "Attempting to find a profile with the name '%s'." % ( + profile_dir + ) + profile_dir = find_profile_dir(profile_dir) + + if not (profile_dir and os.path.exists(profile_dir) and + os.path.isdir(profile_dir)): + print "Can't resolve profile directory; aborting." + sys.exit(1) + + extension_id = get_install_rdf_property(path_to_extension_root, + "em:id") + + extension_file = os.path.join(profile_dir, + "extensions", + extension_id) + files_to_remove = ["compreg.dat", + "xpti.dat"] + for filename in files_to_remove: + abspath = os.path.join(profile_dir, filename) + if os.path.exists(abspath): + os.remove(abspath) + if os.path.exists(extension_file): + if os.path.isdir(extension_file): + shutil.rmtree(extension_file) + else: + os.remove(extension_file) + if cmd == "install": + #if cygwin, change the path to windows format so firefox can understand it + if sys.platform == "cygwin": + file = 'cygpath.exe -w ' + path_to_extension_root + path_to_extension_root = "".join(os.popen(file).readlines()).replace("\n", " ").rstrip() + + extdir = os.path.dirname(extension_file) + if not os.path.exists(extdir): + distutils.dir_util.mkpath(extdir) + fileobj = open(extension_file, "w") + fileobj.write(path_to_extension_root) + fileobj.close() + print "Extension '%s' installed." % extension_id + else: + print "Extension '%s' uninstalled." % extension_id + elif cmd == "build-xpi": + version = get_install_rdf_property(path_to_extension_root, + "em:version") + extname = get_install_rdf_property(path_to_extension_root, + "em:name").lower() + zfname = "%s-%s.xpi" % (extname, version) + zf = zipfile.ZipFile(zfname, + "w", + zipfile.ZIP_DEFLATED) + for dirpath, dirnames, filenames in os.walk(path_to_extension_root): + for filename in filenames: + abspath = os.path.join(dirpath, filename) + arcpath = abspath[len(path_to_extension_root)+1:] + zf.write(abspath, arcpath) + print "Created %s." % zfname + elif cmd == "build-components": + if "TOPSRCDIR" not in os.environ: + print ("Please set the TOPSRCDIR environment variable " + "to the root of your mozilla-central checkout. " + "If you're on Windows, this should be a standard " + "Windows-style path, NOT a unix-style path.") + sys.exit(1) + if "OBJDIR" not in os.environ: + print ("Please set the OBJDIR envirionment variable " + "to the root of your objdir. " + "If you're on Windows, this should be a standard " + "Windows-style path, NOT a unix-style path.") + sys.exit(1) + xpcominfo = get_xpcom_info() + topsrcdir = os.environ["TOPSRCDIR"] + objdir = os.environ["OBJDIR"] + comp_src_dir = os.path.join(g_mydir, "components") + rel_dest_dir = os.path.join("browser", "components", "JSWeakRef") + comp_dest_dir = os.path.join(topsrcdir, rel_dest_dir) + comp_xpi_dir = os.path.join(objdir, "dist", "xpi-stage", + "JSWeakRef-components", "components") + comp_plat_dir = os.path.join( + g_mydir, "JSWeakRef", "platform", + "%(os_target)s_%(xpcomabi)s" % xpcominfo, + "components", + ) + + clear_dir(comp_dest_dir) + clear_dir(comp_xpi_dir) + clear_dir(comp_plat_dir) + + shutil.copytree(comp_src_dir, comp_dest_dir) + + # Ensure that these paths are unix-like on Windows. + sh_pwd = subprocess.Popen(["sh", "-c", "pwd"], + cwd=topsrcdir, + stdout=subprocess.PIPE) + sh_pwd.wait() + unix_topsrcdir = sh_pwd.stdout.read().strip() + unix_rel_dest_dir = rel_dest_dir.replace("\\", "/") + + # We're specifying 'perl' here because we have to for this + # to work on Windows. + run_program(["perl", + os.path.join(topsrcdir, "build", "autoconf", + "make-makefile"), + "-t", unix_topsrcdir, + unix_rel_dest_dir], + cwd=objdir) + run_program(["make"], + cwd=os.path.join(objdir, rel_dest_dir)) + + shutil.copytree(comp_xpi_dir, comp_plat_dir) + for filename in os.listdir(comp_xpi_dir): + shutil.copy(os.path.join(comp_xpi_dir, filename), + xpcominfo["comsd"]) + + for filename in ["compreg.dat", "xpti.dat"]: + fullpath = os.path.join(xpcominfo["comsd"], filename) + if os.path.exists(fullpath): + os.unlink(fullpath) + else: + print "Unknown command '%s'" % cmd + sys.exit(1)