FreeBSD Bugzilla – Attachment 148570 Details for
Bug 193886
[PATCH] games/oolite: Update to v1.80
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Proposed patch (since 371287 revision)
oolite_1.76,4-1.80.diff (text/plain), 105.03 KB, created by
lightside
on 2014-10-23 03:59:59 UTC
(
hide
)
Description:
Proposed patch (since 371287 revision)
Filename:
MIME Type:
Creator:
lightside
Created:
2014-10-23 03:59:59 UTC
Size:
105.03 KB
patch
obsolete
>diff -ruN oolite.orig/Makefile oolite/Makefile >--- oolite.orig/Makefile 2014-10-20 21:36:02.000000000 +0400 >+++ oolite/Makefile 2014-10-23 07:21:27.000000000 +0400 >@@ -2,27 +2,32 @@ > # $FreeBSD: head/games/oolite/Makefile 371287 2014-10-20 17:36:02Z mva $ > > PORTNAME= oolite >-PORTVERSION= 1.76 >-PORTREVISION= 4 >+PORTVERSION= 1.80 > CATEGORIES= games gnustep >-MASTER_SITES= ${MASTER_SITE_BERLIOS} http://jens.ayton.se/oolite/deps/:js >-MASTER_SITE_SUBDIR= oolite-linux >-DISTFILES= ${PORTNAME}-source-${PORTVERSION}${EXTRACT_SUFX} \ >- firefox-4.0.source.js-only.tbz:js >+MASTER_SITES= http://github.com/OoliteProject/oolite/releases/download/1.80b/ >+DISTNAME= ${PORTNAME}-source-${PORTVERSION} > DIST_SUBDIR= oolite >-EXTRACT_ONLY= ${PORTNAME}-source-${PORTVERSION}${EXTRACT_SUFX} > > MAINTAINER= avg@icyb.net.ua > COMMENT= Trade and combat space simulator, clone of Elite > >+LICENSE= CCBYNCSAv3 GPLv2 ZLIB >+LICENSE_COMB= multi >+LICENSE_NAME_CCBYNCSAv3= Creative Commons Attribution-NonCommercial-ShareAlike License version 3.0 >+LICENSE_FILE_CCBYNCSAv3= ${WRKSRC}/Doc/LICENSE.TXT >+LICENSE_PERMS_CCBYNCSAv3= dist-mirror pkg-mirror auto-accept >+ > BUILD_DEPENDS= zip:${PORTSDIR}/archivers/zip \ > ${LOCALBASE}/bin/unzip:${PORTSDIR}/archivers/unzip > LIB_DEPENDS= libespeak.so:${PORTSDIR}/audio/espeak \ >- libnspr4.so:${PORTSDIR}/devel/nspr >+ libnspr4.so:${PORTSDIR}/devel/nspr \ >+ libvorbisfile.so:${PORTSDIR}/audio/libvorbis \ >+ libpng15.so:${PORTSDIR}/graphics/png \ >+ libminizip.so:${PORTSDIR}/archivers/minizip > >-USES= gmake perl5 python:build tar:bzip2 >+USES= gmake openal:al perl5 python:build tar:bzip2 > USE_GL= yes >-USE_SDL= mixer image gfx >+USE_SDL= sdl > USE_GNUSTEP= yes > USE_GNUSTEP_BASE= yes > USE_GNUSTEP_BUILD= yes >@@ -30,23 +35,63 @@ > ALL_TARGET= release-deployment > USE_PERL5= build > >-SUB_FILES= pkg-message >-PKGMESSAGE= ${WRKDIR}/pkg-message >- >-WRKSRC= ${WRKDIR}/${PORTNAME}-source-${PORTVERSION} >- >-post-extract: >- @(cd ${WRKSRC}/deps/Cross-platform-deps && \ >- ${BZIP2_CMD} -dc ${_DISTDIR}/firefox-4.0.source.js-only.tbz | ${TAR} -xf - && \ >- ${MV} mozilla-2.0 mozilla && \ >- ${ECHO_CMD} 'http://jens.ayton.se/oolite/deps/firefox-4.0.source.js-only.tbz' > mozilla/current.url \ >- ) >+SUB_FILES= oolite >+SUB_LIST= GNUSTEP_SYSTEM_TOOLS="${GNUSTEP_SYSTEM_TOOLS}" > >+WRKSRC= ${WRKDIR}/${DISTNAME} >+RELEASEDIR= ${WRKSRC}/oolite.app >+DATADIR= ${GNUSTEP_LOCAL_APPS}/oolite.app >+PORTDATA= Resources >+PORTDOCS= *.pdf CHANGELOG.TXT contributors.txt >+ >+PLIST_FILES+= bin/oolite %%DATADIR%%/oolite \ >+ share/applications/oolite.desktop \ >+ share/pixmaps/oolite-icon.png >+ >+OPTIONS_DEFINE= DOCS >+ >+.include <bsd.port.pre.mk> >+ >+.if ${OSVERSION} < 900014 >+BUILD_DEPENDS+= clang33:${PORTSDIR}/lang/clang33 >+CC= ${LOCALBASE}/bin/clang33 >+CXX= ${LOCALBASE}/bin/clang++33 >+CPP= ${LOCALBASE}/bin/clang-cpp33 >+.elif exists(${CC}) >+CCVERSION!= ${CC} --version >+COMPILER_VERSION= ${CCVERSION:M[0-9].[0-9]*:C/([0-9]).?/\1/g} >+COMPILER_IS_CLANG= ${CCVERSION:Mclang} >+ >+# Check for LLVM/Clang v3.4.1 >+.if ${COMPILER_IS_CLANG} && ${COMPILER_VERSION} == 341 >+# Force to use optimization for size, because of speed optimization error(s) >+# for ${WRKSRC}/src/Core/Scripting/OOJavaScriptEngine.m file >+ADD_OBJCFLAGS= s|-std=c99|-std=c99 -Os| >+.endif >+.endif >+ >+post-patch: .SILENT >+ ${REINPLACE_CMD} -e 's/GNUSTEP_USER_ROOT/GNUSTEP_LOCAL_ROOT/ ; \ >+ s/sdl-config/$${SDL_CONFIG}/ ; \ >+ s|-lstdc++|`$${SDL_CONFIG} --libs` -lstdc++| ; \ >+ s|:src/Core/MiniZip|| ; \ >+ s|-Isrc/Core/MiniZip|-I$${LOCALBASE}/include/minizip| ; \ >+ s|-lz|-lminizip| ; \ >+ /ioapi.c/d ; /unzip.c/d ; \ >+ s|/usr/X11R6|$${LOCALBASE}| ; ${ADD_OBJCFLAGS}' \ >+ ${WRKSRC}/GNUmakefile >+# Conversion needed for unsigned int type for using isfinite function >+ ${REINPLACE_CMD} -e 's|isfinite(uValue)|isfinite((long double)uValue)|' \ >+ ${WRKSRC}/src/Core/Scripting/OOJSPlayerShip.m >+# Change value of the SAVEDIR define >+ ${REINPLACE_CMD} -e 's|oolite-saves|\.oolite-saves|' \ >+ ${WRKSRC}/src/Core/NSFileManagerOOExtensions.h > do-install: >- ${MKDIR} ${STAGEDIR}${PREFIX}/GNUstep/Local/Applications >- ${CP} -R ${WRKSRC}/oolite.app ${STAGEDIR}${PREFIX}/GNUstep/Local/Applications >- ${STRIP_CMD} ${STAGEDIR}${PREFIX}/GNUstep/Local/Applications/oolite.app/oolite >+ cd ${RELEASEDIR} && ${COPYTREE_SHARE} "${PORTDATA}" ${STAGEDIR}${DATADIR} >+ ${INSTALL_SCRIPT} ${WRKDIR}/oolite ${STAGEDIR}${PREFIX}/bin >+ ${INSTALL_PROGRAM} ${RELEASEDIR}/oolite ${STAGEDIR}${DATADIR} > ${INSTALL_DATA} ${WRKSRC}/installers/FreeDesktop/oolite.desktop ${STAGEDIR}${PREFIX}/share/applications > ${INSTALL_DATA} ${WRKSRC}/installers/FreeDesktop/oolite-icon.png ${STAGEDIR}${PREFIX}/share/pixmaps >+ cd ${WRKSRC}/Doc && ${COPYTREE_SHARE} "${PORTDOCS}" ${STAGEDIR}${DOCSDIR} > >-.include <bsd.port.mk> >+.include <bsd.port.post.mk> >diff -ruN oolite.orig/distinfo oolite/distinfo >--- oolite.orig/distinfo 2014-01-22 19:30:13.000000000 +0400 >+++ oolite/distinfo 2014-09-23 06:51:48.000000000 +0400 >@@ -1,4 +1,2 @@ >-SHA256 (oolite/oolite-source-1.76.tar.bz2) = cc5054432b4e1ad316ed5f52c88036cb8fc9732d42969225993f79ae3e93ff11 >-SIZE (oolite/oolite-source-1.76.tar.bz2) = 44739650 >-SHA256 (oolite/firefox-4.0.source.js-only.tbz) = 173b8798043612e50fa7618858c3a92d06f1f439d6d336a5700548cc5d75580a >-SIZE (oolite/firefox-4.0.source.js-only.tbz) = 6198554 >+SHA256 (oolite/oolite-source-1.80.tar.bz2) = a9bea03435cd7fd05b4519a44345e4ff4857a799aef79913733ddc5d7a537bdf >+SIZE (oolite/oolite-source-1.80.tar.bz2) = 139397592 >diff -ruN oolite.orig/files/oolite.in oolite/files/oolite.in >--- oolite.orig/files/oolite.in 1970-01-01 03:00:00.000000000 +0300 >+++ oolite/files/oolite.in 2014-09-24 10:49:38.000000000 +0400 >@@ -0,0 +1,3 @@ >+#!/bin/sh >+ >+%%GNUSTEP_SYSTEM_TOOLS%%/openapp oolite "$@" >diff -ruN oolite.orig/files/patch-GNUmakefile oolite/files/patch-GNUmakefile >--- oolite.orig/files/patch-GNUmakefile 2014-01-22 21:40:44.000000000 +0400 >+++ oolite/files/patch-GNUmakefile 1970-01-01 03:00:00.000000000 +0300 >@@ -1,24 +0,0 @@ >---- GNUmakefile.orig 2011-12-15 12:54:49.000000000 +0200 >-+++ GNUmakefile 2012-02-23 19:59:43.906322555 +0200 >-@@ -4,7 +4,7 @@ include config.make >- vpath %.m src/SDL:src/Core:src/Core/Entities:src/Core/Materials:src/Core/Scripting:src/Core/OXPVerifier:src/Core/Debug >- vpath %.h src/SDL:src/Core:src/Core/Entities:src/Core/Materials:src/Core/Scripting:src/Core/OXPVerifier:src/Core/Debug >- vpath %.c src/SDL:src/Core:src/BSDCompat:src/Core/Debug >--GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_USER_ROOT) >-+GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) >- GNUSTEP_OBJ_DIR_BASENAME := $(GNUSTEP_OBJ_DIR_NAME) >- HOST_ARCH := $(shell echo $(GNUSTEP_HOST_CPU) | sed -e s/i.86/x86/ -e s/amd64/x86_64/ ) >- ifeq ($(GNUSTEP_HOST_OS),mingw32) >-@@ -37,10 +37,10 @@ else >- LIBJS = js_static >- >- ADDITIONAL_INCLUDE_DIRS = -I$(LIBJS_INC_DIR) -Isrc/SDL -Isrc/Core -Isrc/BSDCompat -Isrc/Core/Scripting -Isrc/Core/Materials -Isrc/Core/Entities -Isrc/Core/OXPVerifier -Isrc/Core/Debug -Isrc/Core/Tables >-- ADDITIONAL_OBJC_LIBS = -lGLU -lGL -lX11 -lSDL -lSDL_mixer -lgnustep-base -l$(LIBJS) `nspr-config --libs` -lstdc++ >-+ ADDITIONAL_OBJC_LIBS = -lGLU -lGL -lX11 -lSDL -lSDL_mixer -lgnustep-base -l$(LIBJS) `nspr-config --libs` `sdl-config --libs` -lstdc++ >- ADDITIONAL_CFLAGS = -Wall -DLINUX -DNEED_STRLCPY `sdl-config --cflags` `nspr-config --cflags` >- ADDITIONAL_OBJCFLAGS = -Wall -std=c99 -DLOADSAVEGUI -DLINUX -DXP_UNIX -Wno-import `sdl-config --cflags` `nspr-config --cflags` >-- oolite_LIB_DIRS += -L/usr/X11R6/lib/ -L$(LIBJS_LIB_DIR) >-+ oolite_LIB_DIRS += -L${LOCALBASE}/lib/ -L$(LIBJS_LIB_DIR) >- >- ifeq ($(use_deps),yes) >- oolite_LIB_DIRS += -Ldeps/Linux-deps/$(HOST_ARCH)/lib_linker >diff -ruN oolite.orig/files/patch-deps_Cross-platform-deps_mozilla_js_src_config_system-headers oolite/files/patch-deps_Cross-platform-deps_mozilla_js_src_config_system-headers >--- oolite.orig/files/patch-deps_Cross-platform-deps_mozilla_js_src_config_system-headers 2014-01-22 21:40:44.000000000 +0400 >+++ oolite/files/patch-deps_Cross-platform-deps_mozilla_js_src_config_system-headers 1970-01-01 03:00:00.000000000 +0300 >@@ -1,10 +0,0 @@ >---- deps/Cross-platform-deps/mozilla/js/src/config/system-headers.orig 2012-03-04 13:03:24.492124042 +0200 >-+++ deps/Cross-platform-deps/mozilla/js/src/config/system-headers 2012-03-04 13:03:42.634121018 +0200 >-@@ -609,6 +609,7 @@ proto/exec.h >- psap.h >- Pt.h >- pthread.h >-+pthread_np.h >- pwd.h >- Python.h >- QDOffscreen.h >diff -ruN oolite.orig/files/patch-deps_mozilla-bug771281 oolite/files/patch-deps_mozilla-bug771281 >--- oolite.orig/files/patch-deps_mozilla-bug771281 1970-01-01 03:00:00.000000000 +0300 >+++ oolite/files/patch-deps_mozilla-bug771281 2014-09-23 08:05:08.000000000 +0400 >@@ -0,0 +1,1840 @@ >+diff -ruN deps.orig/mozilla/js/src/shell/Makefile.in deps/mozilla/js/src/shell/Makefile.in >+--- deps.orig/mozilla/js/src/shell/Makefile.in 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/shell/Makefile.in 2014-09-23 07:59:03.000000000 +0400 >+@@ -47,7 +47,6 @@ >+ PROGRAM = js$(BIN_SUFFIX) >+ CPPSRCS = \ >+ js.cpp \ >+- jsworkers.cpp \ >+ $(NULL) >+ >+ DEFINES += -DEXPORT_JS_API >+diff -ruN deps.orig/mozilla/js/src/shell/js.cpp deps/mozilla/js/src/shell/js.cpp >+--- deps.orig/mozilla/js/src/shell/js.cpp 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/shell/js.cpp 2014-09-23 07:59:03.000000000 +0400 >+@@ -91,8 +91,6 @@ >+ #endif /* JSDEBUGGER_C_UI */ >+ #endif /* JSDEBUGGER */ >+ >+-#include "jsworkers.h" >+- >+ #include "jsinterpinlines.h" >+ #include "jsobjinlines.h" >+ #include "jsscriptinlines.h" >+@@ -194,10 +192,6 @@ >+ JSBool gQuitting = JS_FALSE; >+ FILE *gErrFile = NULL; >+ FILE *gOutFile = NULL; >+-#ifdef JS_THREADSAFE >+-JSObject *gWorkers = NULL; >+-js::workers::ThreadPool *gWorkerThreadPool = NULL; >+-#endif >+ >+ static JSBool reportWarnings = JS_TRUE; >+ static JSBool compileOnly = JS_FALSE; >+@@ -1324,10 +1318,6 @@ >+ JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "/ i", &gExitCode); >+ >+ gQuitting = JS_TRUE; >+-#ifdef JS_THREADSAFE >+- if (gWorkerThreadPool) >+- js::workers::terminateAll(JS_GetRuntime(cx), gWorkerThreadPool); >+-#endif >+ return JS_FALSE; >+ } >+ >+@@ -4164,10 +4154,6 @@ >+ gCanceled = true; >+ if (gExitCode == 0) >+ gExitCode = EXITCODE_TIMEOUT; >+-#ifdef JS_THREADSAFE >+- if (gWorkerThreadPool) >+- js::workers::terminateAll(rt, gWorkerThreadPool); >+-#endif >+ JS_TriggerAllOperationCallbacks(rt); >+ >+ static const char msg[] = "Script runs for too long, terminating.\n"; >+@@ -5695,29 +5681,8 @@ >+ #endif /* JSDEBUGGER_C_UI */ >+ #endif /* JSDEBUGGER */ >+ >+-#ifdef JS_THREADSAFE >+- class ShellWorkerHooks : public js::workers::WorkerHooks { >+- public: >+- JSObject *newGlobalObject(JSContext *cx) { >+- return NewGlobalObject(cx, NEW_COMPARTMENT); >+- } >+- }; >+- ShellWorkerHooks hooks; >+- if (!JS_AddNamedObjectRoot(cx, &gWorkers, "Workers") || >+- (gWorkerThreadPool = js::workers::init(cx, &hooks, glob, &gWorkers)) == NULL) { >+- return 1; >+- } >+-#endif >+- >+ int result = ProcessArgs(cx, glob, argv, argc); >+ >+-#ifdef JS_THREADSAFE >+- js::workers::finish(cx, gWorkerThreadPool); >+- JS_RemoveObjectRoot(cx, &gWorkers); >+- if (result == 0) >+- result = gExitCode; >+-#endif >+- >+ #ifdef JSDEBUGGER >+ if (jsdc) { >+ #ifdef JSDEBUGGER_C_UI >+diff -ruN deps.orig/mozilla/js/src/shell/jsworkers.cpp.rej deps/mozilla/js/src/shell/jsworkers.cpp.rej >+--- deps.orig/mozilla/js/src/shell/jsworkers.cpp.rej 1970-01-01 03:00:00.000000000 +0300 >++++ deps/mozilla/js/src/shell/jsworkers.cpp.rej 2014-09-23 07:59:03.000000000 +0400 >+@@ -0,0 +1,1281 @@ >++@@ -1,1280 +0,0 @@ >++-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- >++- * vim: set ts=8 sw=4 et tw=99: >++- * >++- * ***** 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 JavaScript shell workers. >++- * >++- * The Initial Developer of the Original Code is >++- * Mozilla Corporation. >++- * Portions created by the Initial Developer are Copyright (C) 2010 >++- * the Initial Developer. All Rights Reserved. >++- * >++- * Contributor(s): >++- * Jason Orendorff <jorendorff@mozilla.com> >++- * >++- * Alternatively, the contents of this file may be used under the terms of >++- * either of 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 ***** */ >++- >++-#ifdef JS_THREADSAFE >++- >++-#include <algorithm> >++-#include <string.h> >++-#include "prthread.h" >++-#include "prlock.h" >++-#include "prcvar.h" >++-#include "jsapi.h" >++-#include "jscntxt.h" >++-#include "jshashtable.h" >++-#include "jsstdint.h" >++-#include "jslock.h" >++-#include "jsvector.h" >++-#include "jsworkers.h" >++- >++-extern size_t gMaxStackSize; >++- >++-/* >++- * JavaScript shell workers. >++- * >++- * == Object lifetime rules == >++- * >++- * - The ThreadPool lasts from init() to finish(). >++- * >++- * - The ThreadPool owns the MainQueue and the WorkerQueue. Those live from >++- * the time the first Worker is created until finish(). >++- * >++- * - Each JS Worker object has the same lifetime as the corresponding C++ >++- * Worker object. A Worker is live if (a) the Worker JSObject is still >++- * live; (b) the Worker has an incoming event pending or running; (c) it >++- * has sent an outgoing event to its parent that is still pending; or (d) >++- * it has any live child Workers. >++- * >++- * - finish() continues to wait for events until all threads are idle. >++- * >++- * Event objects, however, are basically C++-only. The JS Event objects are >++- * just plain old JSObjects. They don't keep anything alive. >++- * >++- * == Locking scheme == >++- * >++- * When mixing mutexes and the JSAPI request model, there are two choices: >++- * >++- * - Always nest the mutexes in requests. Since threads in requests are not >++- * supposed to block, this means the mutexes must be only briefly held. >++- * >++- * - Never nest the mutexes in requests. Since this allows threads to race >++- * with the GC, trace() methods must go through the mutexes just like >++- * everyone else. >++- * >++- * This code uses the latter approach for all locks. >++- * >++- * In one case, a thread holding a Worker's mutex can acquire the mutex of one >++- * of its child Workers. See Worker::terminateSelf. (This can't deadlock because >++- * the parent-child relationship is a partial order.) >++- */ >++- >++-namespace js { >++-namespace workers { >++- >++-template <class T, class AllocPolicy> >++-class Queue { >++- private: >++- typedef Vector<T, 4, AllocPolicy> Vec; >++- Vec v1; >++- Vec v2; >++- Vec *front; >++- Vec *back; >++- >++- // Queue is not copyable. >++- Queue(const Queue &); >++- Queue & operator=(const Queue &); >++- >++- public: >++- Queue() : front(&v1), back(&v2) {} >++- bool push(T t) { return back->append(t); } >++- bool empty() { return front->empty() && back->empty(); } >++- >++- T pop() { >++- if (front->empty()) { >++- std::reverse(back->begin(), back->end()); >++- Vec *tmp = front; >++- front = back; >++- back = tmp; >++- } >++- T item = front->back(); >++- front->popBack(); >++- return item; >++- } >++- >++- void clear() { >++- v1.clear(); >++- v2.clear(); >++- } >++- >++- void trace(JSTracer *trc) { >++- for (T *p = v1.begin(); p != v1.end(); p++) >++- (*p)->trace(trc); >++- for (T *p = v2.begin(); p != v2.end(); p++) >++- (*p)->trace(trc); >++- } >++-}; >++- >++-class Event; >++-class ThreadPool; >++-class Worker; >++- >++-class WorkerParent { >++- protected: >++- typedef HashSet<Worker *, DefaultHasher<Worker *>, SystemAllocPolicy> ChildSet; >++- ChildSet children; >++- >++- bool initWorkerParent() { return children.init(8); } >++- >++- public: >++- virtual JSLock *getLock() = 0; >++- virtual ThreadPool *getThreadPool() = 0; >++- virtual bool post(Event *item) = 0; // false on OOM or queue closed >++- virtual void trace(JSTracer *trc) = 0; >++- >++- bool addChild(Worker *w) { >++- AutoLock hold(getLock()); >++- return children.put(w) != NULL; >++- } >++- >++- // This must be called only from GC or when all threads are shut down. It >++- // does not bother with locking. >++- void removeChild(Worker *w) { >++- ChildSet::Ptr p = children.lookup(w); >++- JS_ASSERT(p); >++- children.remove(p); >++- } >++- >++- void disposeChildren(); >++-}; >++- >++-template <class T> >++-class ThreadSafeQueue >++-{ >++- protected: >++- Queue<T, SystemAllocPolicy> queue; >++- JSLock *lock; >++- PRCondVar *condvar; >++- bool closed; >++- >++- private: >++- Vector<T, 8, SystemAllocPolicy> busy; >++- >++- protected: >++- ThreadSafeQueue() : lock(NULL), condvar(NULL), closed(false) {} >++- >++- ~ThreadSafeQueue() { >++- if (condvar) >++- JS_DESTROY_CONDVAR(condvar); >++- if (lock) >++- JS_DESTROY_LOCK(lock); >++- } >++- >++- // Called by take() with the lock held. >++- virtual bool shouldStop() { return closed; } >++- >++- public: >++- bool initThreadSafeQueue() { >++- JS_ASSERT(!lock); >++- JS_ASSERT(!condvar); >++- return (lock = JS_NEW_LOCK()) && (condvar = JS_NEW_CONDVAR(lock)); >++- } >++- >++- bool post(T t) { >++- AutoLock hold(lock); >++- if (closed) >++- return false; >++- if (queue.empty()) >++- JS_NOTIFY_ALL_CONDVAR(condvar); >++- return queue.push(t); >++- } >++- >++- void close() { >++- AutoLock hold(lock); >++- closed = true; >++- queue.clear(); >++- JS_NOTIFY_ALL_CONDVAR(condvar); >++- } >++- >++- // The caller must hold the lock. >++- bool take(T *t) { >++- while (queue.empty()) { >++- if (shouldStop()) >++- return false; >++- JS_WAIT_CONDVAR(condvar, JS_NO_TIMEOUT); >++- } >++- *t = queue.pop(); >++- busy.append(*t); >++- return true; >++- } >++- >++- // The caller must hold the lock. >++- void drop(T item) { >++- for (T *p = busy.begin(); p != busy.end(); p++) { >++- if (*p == item) { >++- *p = busy.back(); >++- busy.popBack(); >++- return; >++- } >++- } >++- JS_NOT_REACHED("removeBusy"); >++- } >++- >++- bool lockedIsIdle() { return busy.empty() && queue.empty(); } >++- >++- bool isIdle() { >++- AutoLock hold(lock); >++- return lockedIsIdle(); >++- } >++- >++- void wake() { >++- AutoLock hold(lock); >++- JS_NOTIFY_ALL_CONDVAR(condvar); >++- } >++- >++- void trace(JSTracer *trc) { >++- AutoLock hold(lock); >++- for (T *p = busy.begin(); p != busy.end(); p++) >++- (*p)->trace(trc); >++- queue.trace(trc); >++- } >++-}; >++- >++-class MainQueue; >++- >++-class Event >++-{ >++- protected: >++- virtual ~Event() { JS_ASSERT(!data); } >++- >++- WorkerParent *recipient; >++- Worker *child; >++- uint64 *data; >++- size_t nbytes; >++- >++- public: >++- enum Result { fail = JS_FALSE, ok = JS_TRUE, forwardToParent }; >++- >++- virtual void destroy(JSContext *cx) { >++- JS_free(cx, data); >++-#ifdef DEBUG >++- data = NULL; >++-#endif >++- delete this; >++- } >++- >++- void setChildAndRecipient(Worker *aChild, WorkerParent *aRecipient) { >++- child = aChild; >++- recipient = aRecipient; >++- } >++- >++- bool deserializeData(JSContext *cx, jsval *vp) { >++- return !!JS_ReadStructuredClone(cx, data, nbytes, JS_STRUCTURED_CLONE_VERSION, vp, >++- NULL, NULL); >++- } >++- >++- virtual Result process(JSContext *cx) = 0; >++- >++- inline void trace(JSTracer *trc); >++- >++- template <class EventType> >++- static EventType *createEvent(JSContext *cx, WorkerParent *recipient, Worker *child, >++- jsval v) >++- { >++- uint64 *data; >++- size_t nbytes; >++- if (!JS_WriteStructuredClone(cx, v, &data, &nbytes, NULL, NULL)) >++- return NULL; >++- >++- EventType *event = new EventType; >++- if (!event) { >++- JS_ReportOutOfMemory(cx); >++- return NULL; >++- } >++- event->recipient = recipient; >++- event->child = child; >++- event->data = data; >++- event->nbytes = nbytes; >++- return event; >++- } >++- >++- Result dispatch(JSContext *cx, JSObject *thisobj, const char *dataPropName, >++- const char *methodName, Result noHandler) >++- { >++- if (!data) >++- return fail; >++- >++- JSBool found; >++- if (!JS_HasProperty(cx, thisobj, methodName, &found)) >++- return fail; >++- if (!found) >++- return noHandler; >++- >++- // Create event object. >++- jsval v; >++- if (!deserializeData(cx, &v)) >++- return fail; >++- JSObject *obj = JS_NewObject(cx, NULL, NULL, NULL); >++- if (!obj || !JS_DefineProperty(cx, obj, dataPropName, v, NULL, NULL, 0)) >++- return fail; >++- >++- // Call event handler. >++- jsval argv[1] = { OBJECT_TO_JSVAL(obj) }; >++- jsval rval = JSVAL_VOID; >++- return Result(JS_CallFunctionName(cx, thisobj, methodName, 1, argv, &rval)); >++- } >++-}; >++- >++-typedef ThreadSafeQueue<Event *> EventQueue; >++- >++-class MainQueue : public EventQueue, public WorkerParent >++-{ >++- private: >++- ThreadPool *threadPool; >++- >++- public: >++- explicit MainQueue(ThreadPool *tp) : threadPool(tp) {} >++- >++- ~MainQueue() { >++- JS_ASSERT(queue.empty()); >++- } >++- >++- bool init() { return initThreadSafeQueue() && initWorkerParent(); } >++- >++- void destroy(JSContext *cx) { >++- while (!queue.empty()) >++- queue.pop()->destroy(cx); >++- delete this; >++- } >++- >++- virtual JSLock *getLock() { return lock; } >++- virtual ThreadPool *getThreadPool() { return threadPool; } >++- >++- protected: >++- virtual bool shouldStop(); >++- >++- public: >++- virtual bool post(Event *event) { return EventQueue::post(event); } >++- >++- virtual void trace(JSTracer *trc); >++- >++- void traceChildren(JSTracer *trc) { EventQueue::trace(trc); } >++- >++- JSBool mainThreadWork(JSContext *cx, bool continueOnError) { >++- JSAutoSuspendRequest suspend(cx); >++- AutoLock hold(lock); >++- >++- Event *event; >++- while (take(&event)) { >++- JS_RELEASE_LOCK(lock); >++- Event::Result result; >++- { >++- JSAutoRequest req(cx); >++- result = event->process(cx); >++- if (result == Event::forwardToParent) { >++- // FIXME - pointlessly truncates the string to 8 bits >++- jsval data; >++- JSAutoByteString bytes; >++- if (event->deserializeData(cx, &data) && >++- JSVAL_IS_STRING(data) && >++- bytes.encode(cx, JSVAL_TO_STRING(data))) { >++- JS_ReportError(cx, "%s", bytes.ptr()); >++- } else { >++- JS_ReportOutOfMemory(cx); >++- } >++- result = Event::fail; >++- } >++- if (result == Event::fail && continueOnError) { >++- if (JS_IsExceptionPending(cx) && !JS_ReportPendingException(cx)) >++- JS_ClearPendingException(cx); >++- result = Event::ok; >++- } >++- } >++- JS_ACQUIRE_LOCK(lock); >++- drop(event); >++- event->destroy(cx); >++- if (result != Event::ok) >++- return false; >++- } >++- return true; >++- } >++-}; >++- >++-/* >++- * A queue of workers. >++- * >++- * We keep a queue of workers with pending events, rather than a queue of >++- * events, so that two threads won't try to run a Worker at the same time. >++- */ >++-class WorkerQueue : public ThreadSafeQueue<Worker *> >++-{ >++- private: >++- MainQueue *main; >++- >++- public: >++- explicit WorkerQueue(MainQueue *main) : main(main) {} >++- >++- void work(); >++-}; >++- >++-/* The top-level object that owns everything else. */ >++-class ThreadPool >++-{ >++- private: >++- enum { threadCount = 6 }; >++- >++- JSObject *obj; >++- WorkerHooks *hooks; >++- MainQueue *mq; >++- WorkerQueue *wq; >++- PRThread *threads[threadCount]; >++- int32_t terminating; >++- >++- static JSClass jsClass; >++- >++- static void start(void* arg) { >++- ((WorkerQueue *) arg)->work(); >++- } >++- >++- explicit ThreadPool(WorkerHooks *hooks) : hooks(hooks), mq(NULL), wq(NULL), terminating(0) { >++- for (int i = 0; i < threadCount; i++) >++- threads[i] = NULL; >++- } >++- >++- public: >++- ~ThreadPool() { >++- JS_ASSERT(!mq); >++- JS_ASSERT(!wq); >++- JS_ASSERT(!threads[0]); >++- } >++- >++- static ThreadPool *create(JSContext *cx, WorkerHooks *hooks) { >++- ThreadPool *tp = new ThreadPool(hooks); >++- if (!tp) { >++- JS_ReportOutOfMemory(cx); >++- return NULL; >++- } >++- >++- JSObject *obj = JS_NewObject(cx, &jsClass, NULL, NULL); >++- if (!obj || !JS_SetPrivate(cx, obj, tp)) { >++- delete tp; >++- return NULL; >++- } >++- tp->obj = obj; >++- return tp; >++- } >++- >++- JSObject *asObject() { return obj; } >++- WorkerHooks *getHooks() { return hooks; } >++- WorkerQueue *getWorkerQueue() { return wq; } >++- MainQueue *getMainQueue() { return mq; } >++- bool isTerminating() { return terminating != 0; } >++- >++- /* >++- * Main thread only. Requires request (to prevent GC, which could see the >++- * object in an inconsistent state). >++- */ >++- bool start(JSContext *cx) { >++- JS_ASSERT(!mq && !wq); >++- mq = new MainQueue(this); >++- if (!mq || !mq->init()) { >++- mq->destroy(cx); >++- mq = NULL; >++- return false; >++- } >++- wq = new WorkerQueue(mq); >++- if (!wq || !wq->initThreadSafeQueue()) { >++- delete wq; >++- wq = NULL; >++- mq->destroy(cx); >++- mq = NULL; >++- return false; >++- } >++- JSAutoSuspendRequest suspend(cx); >++- bool ok = true; >++- for (int i = 0; i < threadCount; i++) { >++- threads[i] = PR_CreateThread(PR_USER_THREAD, start, wq, PR_PRIORITY_NORMAL, >++- PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); >++- if (!threads[i]) { >++- shutdown(cx); >++- ok = false; >++- break; >++- } >++- } >++- return ok; >++- } >++- >++- void terminateAll(JSRuntime *rt) { >++- // See comment about JS_ATOMIC_SET in the implementation of >++- // JS_TriggerOperationCallback. >++- JS_ATOMIC_SET(&terminating, 1); >++- JS_TriggerAllOperationCallbacks(rt); >++- } >++- >++- /* This context is used only to free memory. */ >++- void shutdown(JSContext *cx) { >++- wq->close(); >++- for (int i = 0; i < threadCount; i++) { >++- if (threads[i]) { >++- PR_JoinThread(threads[i]); >++- threads[i] = NULL; >++- } >++- } >++- >++- delete wq; >++- wq = NULL; >++- >++- mq->disposeChildren(); >++- mq->destroy(cx); >++- mq = NULL; >++- terminating = 0; >++- } >++- >++- private: >++- static void jsTraceThreadPool(JSTracer *trc, JSObject *obj) { >++- ThreadPool *tp = unwrap(trc->context, obj); >++- if (tp->mq) { >++- tp->mq->traceChildren(trc); >++- tp->wq->trace(trc); >++- } >++- } >++- >++- >++- static void jsFinalize(JSContext *cx, JSObject *obj) { >++- if (ThreadPool *tp = unwrap(cx, obj)) >++- delete tp; >++- } >++- >++- public: >++- static ThreadPool *unwrap(JSContext *cx, JSObject *obj) { >++- JS_ASSERT(JS_GET_CLASS(cx, obj) == &jsClass); >++- return (ThreadPool *) JS_GetPrivate(cx, obj); >++- } >++-}; >++- >++-/* >++- * A Worker is always in one of 4 states, except when it is being initialized >++- * or destroyed, or its lock is held: >++- * - idle (!terminated && current == NULL && events.empty()) >++- * - enqueued (!terminated && current == NULL && !events.empty()) >++- * - busy (!terminated && current != NULL) >++- * - terminated (terminated && current == NULL && events.empty()) >++- * >++- * Separately, there is a terminateFlag that other threads can set >++- * asynchronously to tell the Worker to terminate. >++- */ >++-class Worker : public WorkerParent >++-{ >++- private: >++- ThreadPool *threadPool; >++- WorkerParent *parent; >++- JSObject *object; // Worker object exposed to parent >++- JSContext *context; >++- JSLock *lock; >++- Queue<Event *, SystemAllocPolicy> events; // owning pointers to pending events >++- Event *current; >++- bool terminated; >++- int32_t terminateFlag; >++- >++- static JSClass jsWorkerClass; >++- >++- Worker() >++- : threadPool(NULL), parent(NULL), object(NULL), >++- context(NULL), lock(NULL), current(NULL), terminated(false), terminateFlag(0) {} >++- >++- bool init(JSContext *parentcx, WorkerParent *parent, JSObject *obj) { >++- JS_ASSERT(!threadPool && !this->parent && !object && !lock); >++- >++- if (!initWorkerParent() || !parent->addChild(this)) >++- return false; >++- threadPool = parent->getThreadPool(); >++- this->parent = parent; >++- this->object = obj; >++- lock = JS_NEW_LOCK(); >++- return lock && >++- createContext(parentcx, parent) && >++- JS_SetPrivate(parentcx, obj, this); >++- } >++- >++- bool createContext(JSContext *parentcx, WorkerParent *parent) { >++- JSRuntime *rt = JS_GetRuntime(parentcx); >++- context = JS_NewContext(rt, 8192); >++- if (!context) >++- return false; >++- >++- // The Worker has a strong reference to the global; see jsTraceWorker. >++- // JSOPTION_UNROOTED_GLOBAL ensures that when the worker becomes >++- // unreachable, it and its global object can be collected. Otherwise >++- // the cx->globalObject root would keep them both alive forever. >++- JS_SetOptions(context, JS_GetOptions(parentcx) | JSOPTION_UNROOTED_GLOBAL | >++- JSOPTION_DONT_REPORT_UNCAUGHT); >++- JS_SetVersion(context, JS_GetVersion(parentcx)); >++- JS_SetContextPrivate(context, this); >++- JS_SetOperationCallback(context, jsOperationCallback); >++- JS_BeginRequest(context); >++- >++- JSObject *global = threadPool->getHooks()->newGlobalObject(context); >++- JSObject *post, *proto, *ctor; >++- if (!global) >++- goto bad; >++- JS_SetGlobalObject(context, global); >++- >++- // Because the Worker is completely isolated from the rest of the >++- // runtime, and because any pending events on a Worker keep the Worker >++- // alive, this postMessage function cannot be called after the Worker >++- // is collected. Therefore it's safe to stash a pointer (a weak >++- // reference) to the C++ Worker object in the reserved slot. >++- post = JS_GetFunctionObject(JS_DefineFunction(context, global, "postMessage", >++- (JSNative) jsPostMessageToParent, 1, 0)); >++- if (!post || !JS_SetReservedSlot(context, post, 0, PRIVATE_TO_JSVAL(this))) >++- goto bad; >++- >++- proto = JS_InitClass(context, global, NULL, &jsWorkerClass, jsConstruct, 1, >++- NULL, jsMethods, NULL, NULL); >++- if (!proto) >++- goto bad; >++- >++- ctor = JS_GetConstructor(context, proto); >++- if (!ctor || !JS_SetReservedSlot(context, ctor, 0, PRIVATE_TO_JSVAL(this))) >++- goto bad; >++- >++- JS_EndRequest(context); >++- JS_ClearContextThread(context); >++- return true; >++- >++- bad: >++- JS_EndRequest(context); >++- JS_DestroyContext(context); >++- context = NULL; >++- return false; >++- } >++- >++- static void jsTraceWorker(JSTracer *trc, JSObject *obj) { >++- JS_ASSERT(JS_GET_CLASS(trc->context, obj) == &jsWorkerClass); >++- if (Worker *w = (Worker *) JS_GetPrivate(trc->context, obj)) { >++- w->parent->trace(trc); >++- w->events.trace(trc); >++- if (w->current) >++- w->current->trace(trc); >++- JS_CALL_OBJECT_TRACER(trc, JS_GetGlobalObject(w->context), "Worker global"); >++- } >++- } >++- >++- static void jsFinalize(JSContext *cx, JSObject *obj) { >++- JS_ASSERT(JS_GET_CLASS(cx, obj) == &jsWorkerClass); >++- if (Worker *w = (Worker *) JS_GetPrivate(cx, obj)) >++- delete w; >++- } >++- >++- static JSBool jsOperationCallback(JSContext *cx) { >++- Worker *w = (Worker *) JS_GetContextPrivate(cx); >++- JSAutoSuspendRequest suspend(cx); // avoid nesting w->lock in a request >++- return !w->checkTermination(); >++- } >++- >++- static JSBool jsResolveGlobal(JSContext *cx, JSObject *obj, jsid id, uintN flags, >++- JSObject **objp) >++- { >++- JSBool resolved; >++- >++- if (!JS_ResolveStandardClass(cx, obj, id, &resolved)) >++- return false; >++- if (resolved) >++- *objp = obj; >++- >++- return true; >++- } >++- >++- static JSBool jsPostMessageToParent(JSContext *cx, uintN argc, jsval *vp); >++- static JSBool jsPostMessageToChild(JSContext *cx, uintN argc, jsval *vp); >++- static JSBool jsTerminate(JSContext *cx, uintN argc, jsval *vp); >++- >++- bool checkTermination() { >++- AutoLock hold(lock); >++- return lockedCheckTermination(); >++- } >++- >++- bool lockedCheckTermination() { >++- if (terminateFlag || threadPool->isTerminating()) { >++- terminateSelf(); >++- terminateFlag = 0; >++- } >++- return terminated; >++- } >++- >++- // Caller must hold the lock. >++- void terminateSelf() { >++- terminated = true; >++- while (!events.empty()) >++- events.pop()->destroy(context); >++- >++- // Tell the children to shut down too. An arbitrarily silly amount of >++- // processing could happen before the whole tree is terminated; but >++- // this way we don't have to worry about blowing the C stack. >++- for (ChildSet::Enum e(children); !e.empty(); e.popFront()) >++- e.front()->setTerminateFlag(); // note: nesting locks here >++- } >++- >++- public: >++- ~Worker() { >++- if (parent) >++- parent->removeChild(this); >++- dispose(); >++- } >++- >++- void dispose() { >++- JS_ASSERT(!current); >++- while (!events.empty()) >++- events.pop()->destroy(context); >++- if (lock) { >++- JS_DESTROY_LOCK(lock); >++- lock = NULL; >++- } >++- if (context) { >++- JS_SetContextThread(context); >++- JS_DestroyContextNoGC(context); >++- context = NULL; >++- } >++- object = NULL; >++- >++- // Do not call parent->removeChild(). This is called either from >++- // ~Worker, which calls it for us; or from parent->disposeChildren or >++- // Worker::create, which require that it not be called. >++- parent = NULL; >++- disposeChildren(); >++- } >++- >++- static Worker *create(JSContext *parentcx, WorkerParent *parent, >++- JSString *scriptName, JSObject *obj); >++- >++- JSObject *asObject() { return object; } >++- >++- JSObject *getGlobal() { return JS_GetGlobalObject(context); } >++- >++- WorkerParent *getParent() { return parent; } >++- >++- virtual JSLock *getLock() { return lock; } >++- >++- virtual ThreadPool *getThreadPool() { return threadPool; } >++- >++- bool post(Event *event) { >++- AutoLock hold(lock); >++- if (terminated) >++- return false; >++- if (!current && events.empty() && !threadPool->getWorkerQueue()->post(this)) >++- return false; >++- return events.push(event); >++- } >++- >++- void setTerminateFlag() { >++- AutoLock hold(lock); >++- terminateFlag = true; >++- if (current) >++- JS_TriggerOperationCallback(context); >++- } >++- >++- void processOneEvent(); >++- >++- /* Trace method to be called from C++. */ >++- void trace(JSTracer *trc) { >++- // Just mark the JSObject. If we haven't already been marked, >++- // jsTraceWorker will be called, at which point we'll trace referents. >++- JS_CALL_OBJECT_TRACER(trc, object, "queued Worker"); >++- } >++- >++- static bool getWorkerParentFromConstructor(JSContext *cx, JSObject *ctor, WorkerParent **p) { >++- jsval v; >++- if (!JS_GetReservedSlot(cx, ctor, 0, &v)) >++- return false; >++- if (JSVAL_IS_VOID(v)) { >++- // This means ctor is the root Worker constructor (created in >++- // Worker::initWorkers as opposed to Worker::createContext, which sets up >++- // Worker sandboxes) and nothing is initialized yet. >++- if (!JS_GetReservedSlot(cx, ctor, 1, &v)) >++- return false; >++- ThreadPool *threadPool = (ThreadPool *) JSVAL_TO_PRIVATE(v); >++- if (!threadPool->start(cx)) >++- return false; >++- WorkerParent *parent = threadPool->getMainQueue(); >++- if (!JS_SetReservedSlot(cx, ctor, 0, PRIVATE_TO_JSVAL(parent))) { >++- threadPool->shutdown(cx); >++- return false; >++- } >++- *p = parent; >++- return true; >++- } >++- *p = (WorkerParent *) JSVAL_TO_PRIVATE(v); >++- return true; >++- } >++- >++- static JSBool jsConstruct(JSContext *cx, uintN argc, jsval *vp) { >++- WorkerParent *parent; >++- if (!getWorkerParentFromConstructor(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), &parent)) >++- return false; >++- >++- >++- JSString *scriptName = JS_ValueToString(cx, argc ? JS_ARGV(cx, vp)[0] : JSVAL_VOID); >++- if (!scriptName) >++- return false; >++- >++- JSObject *obj = JS_NewObject(cx, &jsWorkerClass, NULL, NULL); >++- if (!obj || !create(cx, parent, scriptName, obj)) >++- return false; >++- JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj)); >++- return true; >++- } >++- >++- static JSFunctionSpec jsMethods[3]; >++- static JSFunctionSpec jsStaticMethod[2]; >++- >++- static ThreadPool *initWorkers(JSContext *cx, WorkerHooks *hooks, JSObject *global, >++- JSObject **objp) { >++- // Create the ThreadPool object and its JSObject wrapper. >++- ThreadPool *threadPool = ThreadPool::create(cx, hooks); >++- if (!threadPool) >++- return NULL; >++- >++- // Root the ThreadPool JSObject early. >++- *objp = threadPool->asObject(); >++- >++- // Create the Worker constructor. >++- JSObject *proto = JS_InitClass(cx, global, NULL, &jsWorkerClass, >++- jsConstruct, 1, >++- NULL, jsMethods, NULL, NULL); >++- if (!proto) >++- return NULL; >++- >++- // Stash a pointer to the ThreadPool in constructor reserved slot 1. >++- // It will be used later when lazily creating the MainQueue. >++- JSObject *ctor = JS_GetConstructor(cx, proto); >++- if (!JS_SetReservedSlot(cx, ctor, 1, PRIVATE_TO_JSVAL(threadPool))) >++- return NULL; >++- >++- return threadPool; >++- } >++-}; >++- >++-class InitEvent : public Event >++-{ >++- public: >++- static InitEvent *create(JSContext *cx, Worker *worker, JSString *scriptName) { >++- return createEvent<InitEvent>(cx, worker, worker, STRING_TO_JSVAL(scriptName)); >++- } >++- >++- Result process(JSContext *cx) { >++- jsval s; >++- if (!deserializeData(cx, &s)) >++- return fail; >++- JS_ASSERT(JSVAL_IS_STRING(s)); >++- JSAutoByteString filename(cx, JSVAL_TO_STRING(s)); >++- if (!filename) >++- return fail; >++- >++- JSObject *scriptObj = JS_CompileFile(cx, child->getGlobal(), filename.ptr()); >++- if (!scriptObj) >++- return fail; >++- >++- AutoValueRooter rval(cx); >++- JSBool ok = JS_ExecuteScript(cx, child->getGlobal(), scriptObj, Jsvalify(rval.addr())); >++- return Result(ok); >++- } >++-}; >++- >++-class DownMessageEvent : public Event >++-{ >++- public: >++- static DownMessageEvent *create(JSContext *cx, Worker *child, jsval data) { >++- return createEvent<DownMessageEvent>(cx, child, child, data); >++- } >++- >++- Result process(JSContext *cx) { >++- return dispatch(cx, child->getGlobal(), "data", "onmessage", ok); >++- } >++-}; >++- >++-class UpMessageEvent : public Event >++-{ >++- public: >++- static UpMessageEvent *create(JSContext *cx, Worker *child, jsval data) { >++- return createEvent<UpMessageEvent>(cx, child->getParent(), child, data); >++- } >++- >++- Result process(JSContext *cx) { >++- return dispatch(cx, child->asObject(), "data", "onmessage", ok); >++- } >++-}; >++- >++-class ErrorEvent : public Event >++-{ >++- public: >++- static ErrorEvent *create(JSContext *cx, Worker *child) { >++- JSString *data = NULL; >++- jsval exc; >++- if (JS_GetPendingException(cx, &exc)) { >++- AutoValueRooter tvr(cx, Valueify(exc)); >++- JS_ClearPendingException(cx); >++- >++- // Determine what error message to put in the error event. >++- // If exc.message is a string, use that; otherwise use String(exc). >++- // (This is a little different from what web workers do.) >++- if (JSVAL_IS_OBJECT(exc)) { >++- jsval msg; >++- if (!JS_GetProperty(cx, JSVAL_TO_OBJECT(exc), "message", &msg)) >++- JS_ClearPendingException(cx); >++- else if (JSVAL_IS_STRING(msg)) >++- data = JSVAL_TO_STRING(msg); >++- } >++- if (!data) { >++- data = JS_ValueToString(cx, exc); >++- if (!data) >++- return NULL; >++- } >++- } >++- return createEvent<ErrorEvent>(cx, child->getParent(), child, >++- data ? STRING_TO_JSVAL(data) : JSVAL_VOID); >++- } >++- >++- Result process(JSContext *cx) { >++- return dispatch(cx, child->asObject(), "message", "onerror", forwardToParent); >++- } >++-}; >++- >++-} /* namespace workers */ >++-} /* namespace js */ >++- >++-using namespace js::workers; >++- >++-void >++-WorkerParent::disposeChildren() >++-{ >++- for (ChildSet::Enum e(children); !e.empty(); e.popFront()) { >++- e.front()->dispose(); >++- e.removeFront(); >++- } >++-} >++- >++-bool >++-MainQueue::shouldStop() >++-{ >++- // Note: This deliberately nests WorkerQueue::lock in MainQueue::lock. >++- // Releasing MainQueue::lock would risk a race -- isIdle() could return >++- // false, but the workers could become idle before we reacquire >++- // MainQueue::lock and go to sleep, and we would wait on the condvar >++- // forever. >++- return closed || threadPool->getWorkerQueue()->isIdle(); >++-} >++- >++-void >++-MainQueue::trace(JSTracer *trc) >++-{ >++- JS_CALL_OBJECT_TRACER(trc, threadPool->asObject(), "MainQueue"); >++-} >++- >++-void >++-WorkerQueue::work() { >++- AutoLock hold(lock); >++- >++- Worker *w; >++- while (take(&w)) { // can block outside the mutex >++- JS_RELEASE_LOCK(lock); >++- w->processOneEvent(); // enters request on w->context >++- JS_ACQUIRE_LOCK(lock); >++- drop(w); >++- >++- if (lockedIsIdle()) { >++- JS_RELEASE_LOCK(lock); >++- main->wake(); >++- JS_ACQUIRE_LOCK(lock); >++- } >++- } >++-} >++- >++-const bool mswin = >++-#ifdef XP_WIN >++- true >++-#else >++- false >++-#endif >++- ; >++- >++-template <class Ch> bool >++-IsAbsolute(const Ch *filename) >++-{ >++- return filename[0] == '/' || >++- (mswin && (filename[0] == '\\' || (filename[0] != '\0' && filename[1] == ':'))); >++-} >++- >++-// Note: base is a filename, not a directory name. >++-static JSString * >++-ResolveRelativePath(JSContext *cx, const char *base, JSString *filename) >++-{ >++- size_t fileLen = JS_GetStringLength(filename); >++- const jschar *fileChars = JS_GetStringCharsZ(cx, filename); >++- if (!fileChars) >++- return NULL; >++- >++- if (IsAbsolute(fileChars)) >++- return filename; >++- >++- // Strip off the filename part of base. >++- size_t dirLen = -1; >++- for (size_t i = 0; base[i]; i++) { >++- if (base[i] == '/' || (mswin && base[i] == '\\')) >++- dirLen = i; >++- } >++- >++- // If base is relative and contains no directories, use filename unchanged. >++- if (!IsAbsolute(base) && dirLen == (size_t) -1) >++- return filename; >++- >++- // Otherwise return base[:dirLen + 1] + filename. >++- js::Vector<jschar, 0, js::ContextAllocPolicy> result(cx); >++- size_t nchars; >++- if (!JS_DecodeBytes(cx, base, dirLen + 1, NULL, &nchars)) >++- return NULL; >++- if (!result.reserve(dirLen + 1 + fileLen)) { >++- JS_ReportOutOfMemory(cx); >++- return NULL; >++- } >++- JS_ALWAYS_TRUE(result.resize(dirLen + 1)); >++- if (!JS_DecodeBytes(cx, base, dirLen + 1, result.begin(), &nchars)) >++- return NULL; >++- JS_ALWAYS_TRUE(result.append(fileChars, fileLen)); >++- return JS_NewUCStringCopyN(cx, result.begin(), result.length()); >++-} >++- >++-Worker * >++-Worker::create(JSContext *parentcx, WorkerParent *parent, JSString *scriptName, JSObject *obj) >++-{ >++- Worker *w = new Worker(); >++- if (!w || !w->init(parentcx, parent, obj)) { >++- delete w; >++- return NULL; >++- } >++- >++- JSStackFrame *frame = JS_GetScriptedCaller(parentcx, NULL); >++- const char *base = JS_GetScriptFilename(parentcx, JS_GetFrameScript(parentcx, frame)); >++- JSString *scriptPath = ResolveRelativePath(parentcx, base, scriptName); >++- if (!scriptPath) >++- return NULL; >++- >++- // Post an InitEvent to run the initialization script. >++- Event *event = InitEvent::create(parentcx, w, scriptPath); >++- if (!event) >++- return NULL; >++- if (!w->events.push(event) || !w->threadPool->getWorkerQueue()->post(w)) { >++- event->destroy(parentcx); >++- JS_ReportOutOfMemory(parentcx); >++- w->dispose(); >++- return NULL; >++- } >++- return w; >++-} >++- >++-void >++-Worker::processOneEvent() >++-{ >++- Event *event; >++- { >++- AutoLock hold1(lock); >++- if (lockedCheckTermination() || events.empty()) >++- return; >++- >++- event = current = events.pop(); >++- } >++- >++- JS_SetContextThread(context); >++- JS_SetNativeStackQuota(context, gMaxStackSize); >++- >++- Event::Result result; >++- { >++- JSAutoRequest req(context); >++- result = event->process(context); >++- } >++- >++- // Note: we have to leave the above request before calling parent->post or >++- // checkTermination, both of which acquire locks. >++- if (result == Event::forwardToParent) { >++- event->setChildAndRecipient(this, parent); >++- if (parent->post(event)) { >++- event = NULL; // to prevent it from being deleted below >++- } else { >++- JS_ReportOutOfMemory(context); >++- result = Event::fail; >++- } >++- } >++- if (result == Event::fail && !checkTermination()) { >++- JSAutoRequest req(context); >++- Event *err = ErrorEvent::create(context, this); >++- if (err && !parent->post(err)) { >++- JS_ReportOutOfMemory(context); >++- err->destroy(context); >++- err = NULL; >++- } >++- if (!err) { >++- // FIXME - out of memory, probably should panic >++- } >++- } >++- >++- if (event) >++- event->destroy(context); >++- JS_ClearContextThread(context); >++- >++- { >++- AutoLock hold2(lock); >++- current = NULL; >++- if (!lockedCheckTermination() && !events.empty()) { >++- // Re-enqueue this worker. OOM here effectively kills the worker. >++- if (!threadPool->getWorkerQueue()->post(this)) >++- JS_ReportOutOfMemory(context); >++- } >++- } >++-} >++- >++-JSBool >++-Worker::jsPostMessageToParent(JSContext *cx, uintN argc, jsval *vp) >++-{ >++- jsval workerval; >++- if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), 0, &workerval)) >++- return false; >++- Worker *w = (Worker *) JSVAL_TO_PRIVATE(workerval); >++- >++- { >++- JSAutoSuspendRequest suspend(cx); // avoid nesting w->lock in a request >++- if (w->checkTermination()) >++- return false; >++- } >++- >++- jsval data = argc > 0 ? JS_ARGV(cx, vp)[0] : JSVAL_VOID; >++- Event *event = UpMessageEvent::create(cx, w, data); >++- if (!event) >++- return false; >++- if (!w->parent->post(event)) { >++- event->destroy(cx); >++- JS_ReportOutOfMemory(cx); >++- return false; >++- } >++- JS_SET_RVAL(cx, vp, JSVAL_VOID); >++- return true; >++-} >++- >++-JSBool >++-Worker::jsPostMessageToChild(JSContext *cx, uintN argc, jsval *vp) >++-{ >++- JSObject *workerobj = JS_THIS_OBJECT(cx, vp); >++- if (!workerobj) >++- return false; >++- Worker *w = (Worker *) JS_GetInstancePrivate(cx, workerobj, &jsWorkerClass, JS_ARGV(cx, vp)); >++- if (!w) { >++- if (!JS_IsExceptionPending(cx)) >++- JS_ReportError(cx, "Worker was shut down"); >++- return false; >++- } >++- >++- jsval data = argc > 0 ? JS_ARGV(cx, vp)[0] : JSVAL_VOID; >++- Event *event = DownMessageEvent::create(cx, w, data); >++- if (!event) >++- return false; >++- if (!w->post(event)) { >++- JS_ReportOutOfMemory(cx); >++- return false; >++- } >++- JS_SET_RVAL(cx, vp, JSVAL_VOID); >++- return true; >++-} >++- >++-JSBool >++-Worker::jsTerminate(JSContext *cx, uintN argc, jsval *vp) >++-{ >++- JS_SET_RVAL(cx, vp, JSVAL_VOID); >++- >++- JSObject *workerobj = JS_THIS_OBJECT(cx, vp); >++- if (!workerobj) >++- return false; >++- Worker *w = (Worker *) JS_GetInstancePrivate(cx, workerobj, &jsWorkerClass, JS_ARGV(cx, vp)); >++- if (!w) >++- return !JS_IsExceptionPending(cx); // ok to terminate twice >++- >++- JSAutoSuspendRequest suspend(cx); >++- w->setTerminateFlag(); >++- return true; >++-} >++- >++-void >++-Event::trace(JSTracer *trc) >++-{ >++- if (recipient) >++- recipient->trace(trc); >++- if (child) >++- JS_CALL_OBJECT_TRACER(trc, child->asObject(), "worker"); >++-} >++- >++-JSClass ThreadPool::jsClass = { >++- "ThreadPool", JSCLASS_HAS_PRIVATE | JSCLASS_MARK_IS_TRACE, >++- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, >++- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, jsFinalize, >++- NULL, NULL, NULL, NULL, >++- NULL, NULL, JS_CLASS_TRACE(jsTraceThreadPool), NULL >++-}; >++- >++-JSClass Worker::jsWorkerClass = { >++- "Worker", JSCLASS_HAS_PRIVATE | JSCLASS_MARK_IS_TRACE, >++- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, >++- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, jsFinalize, >++- NULL, NULL, NULL, NULL, >++- NULL, NULL, JS_CLASS_TRACE(jsTraceWorker), NULL >++-}; >++- >++-JSFunctionSpec Worker::jsMethods[3] = { >++- JS_FN("postMessage", Worker::jsPostMessageToChild, 1, 0), >++- JS_FN("terminate", Worker::jsTerminate, 0, 0), >++- JS_FS_END >++-}; >++- >++-ThreadPool * >++-js::workers::init(JSContext *cx, WorkerHooks *hooks, JSObject *global, JSObject **rootp) >++-{ >++- return Worker::initWorkers(cx, hooks, global, rootp); >++-} >++- >++-void >++-js::workers::terminateAll(JSRuntime *rt, ThreadPool *tp) >++-{ >++- tp->terminateAll(rt); >++-} >++- >++-void >++-js::workers::finish(JSContext *cx, ThreadPool *tp) >++-{ >++- if (MainQueue *mq = tp->getMainQueue()) { >++- JS_ALWAYS_TRUE(mq->mainThreadWork(cx, true)); >++- tp->shutdown(cx); >++- } >++-} >++- >++-#endif /* JS_THREADSAFE */ >+diff -ruN deps.orig/mozilla/js/src/shell/jsworkers.h deps/mozilla/js/src/shell/jsworkers.h >+--- deps.orig/mozilla/js/src/shell/jsworkers.h 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/shell/jsworkers.h 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,93 +0,0 @@ >+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- >+- * vim: set ts=8 sw=4 et tw=99: >+- * >+- * ***** 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 JavaScript shell workers. >+- * >+- * The Initial Developer of the Original Code is >+- * Mozilla Corporation. >+- * Portions created by the Initial Developer are Copyright (C) 2010 >+- * the Initial Developer. All Rights Reserved. >+- * >+- * Contributor(s): >+- * Jason Orendorff <jorendorff@mozilla.com> >+- * >+- * Alternatively, the contents of this file may be used under the terms of >+- * either of 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 ***** */ >+- >+-#ifndef jsworkers_h___ >+-#define jsworkers_h___ >+- >+-#ifdef JS_THREADSAFE >+- >+-#include "jsapi.h" >+- >+-/* >+- * Workers for the JS shell. >+- * >+- * Note: The real implementation of DOM Workers is in dom/src/threads. >+- */ >+-namespace js { >+- namespace workers { >+- class ThreadPool; >+- >+- class WorkerHooks { >+- public: >+- virtual JSObject *newGlobalObject(JSContext *cx) = 0; >+- virtual ~WorkerHooks() {} >+- }; >+- >+- /* >+- * Initialize workers. This defines the Worker constructor on global. >+- * Requires request. rootp must point to a GC root. >+- * >+- * On success, *rootp receives a pointer to an object, and init returns >+- * a non-null value. The caller must keep the object rooted and must >+- * pass it to js::workers::finish later. >+- */ >+- ThreadPool *init(JSContext *cx, WorkerHooks *hooks, JSObject *global, JSObject **rootp); >+- >+- /* Asynchronously signal for all workers to terminate. >+- * >+- * Call this before calling finish() to shut down without waiting for >+- * all messages to be proceesed. >+- */ >+- void terminateAll(JSRuntime *rt, ThreadPool *tp); >+- >+- /* >+- * Finish running any workers, shut down the thread pool, and free all >+- * resources associated with workers. The application must call this >+- * before shutting down the runtime, and not during GC. >+- * >+- * Requires request. >+- */ >+- void finish(JSContext *cx, ThreadPool *tp); >+- } >+-} >+- >+-#endif /* JS_THREADSAFE */ >+- >+-#endif /* jsworkers_h___ */ >+diff -ruN deps.orig/mozilla/js/src/tests/browser.js deps/mozilla/js/src/tests/browser.js >+--- deps.orig/mozilla/js/src/tests/browser.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/browser.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -767,17 +767,6 @@ >+ document.write(s); >+ } >+ >+-var JSTest = { >+- waitForExplicitFinish: function () { >+- gDelayTestDriverEnd = true; >+- }, >+- >+- testFinished: function () { >+- gDelayTestDriverEnd = false; >+- jsTestDriverEnd(); >+- } >+-}; >+- >+ function jsTestDriverEnd() >+ { >+ // gDelayTestDriverEnd is used to >+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/jstests.list deps/mozilla/js/src/tests/js1_8_5/extensions/jstests.list >+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/jstests.list 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/js1_8_5/extensions/jstests.list 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,13 +1,6 @@ >+ url-prefix ../../jsreftest.html?test=js1_8_5/extensions/ >+ script typedarray.js >+ script typedarray-prototype.js >+-skip-if(!xulRuntime.shell) script worker-error.js # these tests sometimes hang in browser, bug 559954, bug 562333 >+-skip-if(!xulRuntime.shell) script worker-error-propagation.js >+-skip-if(!xulRuntime.shell) script worker-fib.js >+-skip-if(!xulRuntime.shell) script worker-init.js >+-skip-if(!xulRuntime.shell) script worker-simple.js >+-skip-if(!xulRuntime.shell) script worker-terminate.js >+-skip-if(!xulRuntime.shell) script worker-timeout.js >+ script scripted-proxies.js >+ script array-length-protochange.js >+ script parseInt-octal.js >+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-error-child.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-error-child.js >+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-error-child.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-error-child.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,9 +0,0 @@ >+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+-/* >+- * Any copyright is dedicated to the Public Domain. >+- * http://creativecommons.org/licenses/publicdomain/ >+- * Contributor: Jason Orendorff <jorendorff@mozilla.com> >+- */ >+-function onmessage(event) { >+- throw new Error("fail"); >+-} >+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-error-propagation-child.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-error-propagation-child.js >+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-error-propagation-child.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-error-propagation-child.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,16 +0,0 @@ >+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+-/* >+- * Any copyright is dedicated to the Public Domain. >+- * http://creativecommons.org/licenses/publicdomain/ >+- * Contributor: Jason Orendorff <jorendorff@mozilla.com> >+- */ >+- >+-function onmessage(event) { >+- var n = +event.data; >+- if (n == 0) >+- throw new Error("boom"); >+- var w = new Worker(workerDir + "worker-error-propagation-child.js"); >+- w.onmessage = function (event) { postMessage(event.data); }; >+- // No w.onerror here. We are testing error propagation when it is absent. >+- w.postMessage(n - 1 + ""); >+-} >+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-error-propagation.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-error-propagation.js >+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-error-propagation.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-error-propagation.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,20 +0,0 @@ >+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+-/* >+- * Any copyright is dedicated to the Public Domain. >+- * http://creativecommons.org/licenses/publicdomain/ >+- * Contributor: Jason Orendorff <jorendorff@mozilla.com> >+- */ >+- >+-if (typeof Worker != 'undefined') { >+- JSTest.waitForExplicitFinish(); >+- var w = Worker(workerDir + "worker-error-propagation-child.js"); >+- var errors = 0; >+- w.onmessage = function () { throw new Error("no reply expected"); }; >+- w.onerror = function (event) { >+- reportCompare("string", typeof event.message, "typeof event.message"); >+- JSTest.testFinished(); >+- }; >+- w.postMessage("5"); >+-} else { >+- reportCompare(0, 0, " PASSED! Test skipped. Shell workers required."); >+-} >+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-error.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-error.js >+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-error.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-error.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,21 +0,0 @@ >+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+-/* >+- * Any copyright is dedicated to the Public Domain. >+- * http://creativecommons.org/licenses/publicdomain/ >+- * Contributor: Jason Orendorff <jorendorff@mozilla.com> >+- */ >+- >+-if (typeof Worker != 'undefined') { >+- JSTest.waitForExplicitFinish(); >+- >+- // The script throws new Error("fail") on first message. >+- var w = Worker(workerDir + "worker-error-child.js"); >+- var a = []; >+- w.onerror = function (event) { >+- reportCompare("fail", event.message, "worker-error"); >+- JSTest.testFinished(); >+- }; >+- w.postMessage("hello"); >+-} else { >+- reportCompare(0, 0, "Test skipped. Shell workers required."); >+-} >+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-fib-child.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-fib-child.js >+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-fib-child.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-fib-child.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,27 +0,0 @@ >+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+-/* >+- * Any copyright is dedicated to the Public Domain. >+- * http://creativecommons.org/licenses/publicdomain/ >+- * Contributor: Jason Orendorff <jorendorff@mozilla.com> >+- */ >+- >+-function onmessage(event) { >+- var a = event.data.split(/\t/); >+- var n = Number(a[0]); >+- var workerDir = a[1]; >+- >+- if (n <= 1) { >+- postMessage("" + n); >+- } else { >+- var w1 = new Worker(workerDir + "worker-fib-child.js"), >+- w2 = new Worker(workerDir + "worker-fib-child.js"); >+- var a = []; >+- w1.onmessage = w2.onmessage = function(event) { >+- a.push(+event.data); >+- if (a.length == 2) >+- postMessage(a[0] + a[1] + ""); >+- }; >+- w1.postMessage(n - 1 + "\t" + workerDir); >+- w2.postMessage(n - 2 + "\t" + workerDir); >+- } >+-} >+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-fib.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-fib.js >+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-fib.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-fib.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,18 +0,0 @@ >+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+-/* >+- * Any copyright is dedicated to the Public Domain. >+- * http://creativecommons.org/licenses/publicdomain/ >+- * Contributor: Jason Orendorff <jorendorff@mozilla.com> >+- */ >+- >+-if (typeof Worker != 'undefined') { >+- JSTest.waitForExplicitFinish(); >+- var w = Worker(workerDir + "worker-fib-child.js"); >+- w.onmessage = function (event) { >+- reportCompare("55", event.data, "worker-fib"); >+- JSTest.testFinished(); >+- }; >+- w.postMessage("10\t" + workerDir); // 0 1 1 2 3 5 8 13 21 34 55 >+-} else { >+- reportCompare(0, 0, "Test skipped. Shell workers required."); >+-} >+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-init-child.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-init-child.js >+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-init-child.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-init-child.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,8 +0,0 @@ >+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+-/* >+- * Any copyright is dedicated to the Public Domain. >+- * http://creativecommons.org/licenses/publicdomain/ >+- * Contributor: Jason Orendorff <jorendorff@mozilla.com> >+- */ >+-postMessage('do your worst'); >+-for (;;) ; >+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-init.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-init.js >+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-init.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-init.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,19 +0,0 @@ >+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+-/* >+- * Any copyright is dedicated to the Public Domain. >+- * http://creativecommons.org/licenses/publicdomain/ >+- * Contributor: Jason Orendorff <jorendorff@mozilla.com> >+- */ >+- >+-if (typeof Worker != 'undefined') { >+- JSTest.waitForExplicitFinish(); >+- // Messages sent during initialization are a corner case, but in any case >+- // they should be delivered (no waiting until initialization is complete). >+- var w = new Worker(workerDir + "worker-init-child.js"); // posts a message, then loops forever >+- w.onmessage = function (event) { >+- reportCompare(0, 0, "worker-init"); >+- JSTest.testFinished(); >+- }; >+-} else { >+- reportCompare(0, 0, "Test skipped. Shell workers required."); >+-} >+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-simple-child.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-simple-child.js >+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-simple-child.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-simple-child.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,8 +0,0 @@ >+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+-/* >+- * Any copyright is dedicated to the Public Domain. >+- * http://creativecommons.org/licenses/publicdomain/ >+- * Contributor: Jason Orendorff <jorendorff@mozilla.com> >+- */ >+- >+-onmessage = function (event) { postMessage(event.data); }; >+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-simple.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-simple.js >+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-simple.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-simple.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,20 +0,0 @@ >+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+-/* >+- * Any copyright is dedicated to the Public Domain. >+- * http://creativecommons.org/licenses/publicdomain/ >+- * Contributor: Jason Orendorff <jorendorff@mozilla.com> >+- */ >+- >+-if (typeof Worker != 'undefined') { >+- JSTest.waitForExplicitFinish(); >+- var w = new Worker(workerDir + "worker-simple-child.js"); >+- var a = []; >+- w.onmessage = function (event) { >+- a.push(event.data); >+- reportCompare(0, 0, "worker-simple"); >+- JSTest.testFinished(); >+- }; >+- w.postMessage("hello"); >+-} else { >+- reportCompare(0, 0, "Test skipped. Shell workers required."); >+-} >+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate-child.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate-child.js >+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate-child.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate-child.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,13 +0,0 @@ >+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+-/* >+- * Any copyright is dedicated to the Public Domain. >+- * http://creativecommons.org/licenses/publicdomain/ >+- * Contributor: Jason Orendorff <jorendorff@mozilla.com> >+- */ >+- >+-onmessage = function (event) { >+- var workerDir = event.message; >+- var child = new Worker(workerDir + 'worker-terminate-iloop.js'); // loops forever >+- child.terminate(); >+- postMessage("killed"); >+-}; >+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate-iloop.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate-iloop.js >+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate-iloop.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate-iloop.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,9 +0,0 @@ >+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+-/* >+- * Any copyright is dedicated to the Public Domain. >+- * http://creativecommons.org/licenses/publicdomain/ >+- * Contributor: Jason Orendorff <jorendorff@mozilla.com> >+- */ >+- >+-for (;;) >+- ; >+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate.js >+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,37 +0,0 @@ >+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+-/* >+- * Any copyright is dedicated to the Public Domain. >+- * http://creativecommons.org/licenses/publicdomain/ >+- * Contributor: Jason Orendorff <jorendorff@mozilla.com> >+- */ >+- >+-if (typeof Worker != 'undefined') { >+- JSTest.waitForExplicitFinish(); >+- >+- // This tests that a parent worker can terminate a child. We run the test >+- // several times serially. If terminate() doesn't work, the runaway Workers >+- // will soon outnumber the number of threads in the thread pool, and we >+- // will deadlock. >+- var i = 0; >+- >+- function next() { >+- if (++i == 10) { >+- reportCompare(0, 0, "worker-terminate"); >+- JSTest.testFinished(); >+- return; >+- } >+- >+- var w = new Worker(workerDir + "worker-terminate-child.js"); >+- w.onmessage = function (event) { >+- reportCompare("killed", event.data, "killed runaway worker #" + i); >+- next(); >+- }; >+- w.onerror = function (event) { >+- reportCompare(0, 1, "Got error: " + event.message); >+- }; >+- w.postMessage(workerDir); >+- } >+- next(); >+-} else { >+- reportCompare(0, 0, "Test skipped. Shell workers required."); >+-} >+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-timeout-child.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-timeout-child.js >+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-timeout-child.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-timeout-child.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,9 +0,0 @@ >+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+-/* >+- * Any copyright is dedicated to the Public Domain. >+- * http://creativecommons.org/licenses/publicdomain/ >+- * Contributor: Jason Orendorff >+- */ >+- >+-for (;;) >+- ; >+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-timeout.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-timeout.js >+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-timeout.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-timeout.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -1,18 +0,0 @@ >+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+-/* >+- * Any copyright is dedicated to the Public Domain. >+- * http://creativecommons.org/licenses/publicdomain/ >+- * Contributor: Jason Orendorff >+- */ >+- >+-if (typeof timeout == 'function' && typeof Worker != 'undefined') { >+- // We don't actually ever call JSTest.testFinished(); instead we >+- // time out and exit the shell with exit code 6. >+- JSTest.waitForExplicitFinish(); >+- expectExitCode(6); >+- timeout(1.0); >+- for (var i = 0; i < 5; i++) >+- new Worker(workerDir + "worker-timeout-child.js"); // just loops forever >+-} else { >+- reportCompare(0, 0, "Test skipped. Shell workers and timeout required."); >+-} >+diff -ruN deps.orig/mozilla/js/src/tests/shell.js deps/mozilla/js/src/tests/shell.js >+--- deps.orig/mozilla/js/src/tests/shell.js 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/tests/shell.js 2014-09-23 07:59:03.000000000 +0400 >+@@ -833,18 +833,6 @@ >+ } >+ } >+ >+-var JSTest = { >+- waitForExplicitFinish: function () { >+- gDelayTestDriverEnd = true; >+- }, >+- >+- testFinished: function () { >+- gDelayTestDriverEnd = false; >+- jsTestDriverEnd(); >+- quit(); >+- } >+-}; >+- >+ function jsTestDriverEnd() >+ { >+ // gDelayTestDriverEnd is used to >diff -ruN oolite.orig/files/patch-deps_mozilla_js_src_configure oolite/files/patch-deps_mozilla_js_src_configure >--- oolite.orig/files/patch-deps_mozilla_js_src_configure 1970-01-01 03:00:00.000000000 +0300 >+++ oolite/files/patch-deps_mozilla_js_src_configure 2014-09-24 12:46:54.000000000 +0400 >@@ -0,0 +1,12 @@ >+--- deps/mozilla/js/src/configure.orig 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/configure 2014-09-24 04:01:12.000000000 +0400 >+@@ -9547,7 +9547,8 @@ >+ >+ echo "$ac_t""$ac_cv_have_visibility_builtin_bug" 1>&6 >+ if test "$ac_cv_have_visibility_builtin_bug" = "no" -a \ >+- "$ac_cv_have_visibility_class_bug" = "no"; then >++ "$ac_cv_have_visibility_class_bug" = "no" -a \ >++ "$OS_ARCH" != "FreeBSD" ; then >+ VISIBILITY_FLAGS='-I$(DIST)/system_wrappers_js -include $(topsrcdir)/config/gcc_hidden.h' >+ WRAP_SYSTEM_INCLUDES=1 >+ STL_FLAGS='-I$(DIST)/stl_wrappers' >diff -ruN oolite.orig/files/patch-deps_mozilla_js_src_configure.in oolite/files/patch-deps_mozilla_js_src_configure.in >--- oolite.orig/files/patch-deps_mozilla_js_src_configure.in 1970-01-01 03:00:00.000000000 +0300 >+++ oolite/files/patch-deps_mozilla_js_src_configure.in 2014-09-24 12:47:08.000000000 +0400 >@@ -0,0 +1,12 @@ >+--- deps/mozilla/js/src/configure.in.orig 2014-06-30 12:54:39.000000000 +0400 >++++ deps/mozilla/js/src/configure.in 2014-09-23 08:13:19.000000000 +0400 >+@@ -3378,7 +3378,8 @@ >+ rm -f conftest.{c,S} >+ ]) >+ if test "$ac_cv_have_visibility_builtin_bug" = "no" -a \ >+- "$ac_cv_have_visibility_class_bug" = "no"; then >++ "$ac_cv_have_visibility_class_bug" = "no" -a \ >++ "$OS_ARCH" != "FreeBSD" ; then >+ VISIBILITY_FLAGS='-I$(DIST)/system_wrappers_js -include $(topsrcdir)/config/gcc_hidden.h' >+ WRAP_SYSTEM_INCLUDES=1 >+ STL_FLAGS='-I$(DIST)/stl_wrappers' >diff -ruN oolite.orig/files/patch-deps_mozilla_js_src_jsscript.h oolite/files/patch-deps_mozilla_js_src_jsscript.h >--- oolite.orig/files/patch-deps_mozilla_js_src_jsscript.h 1970-01-01 03:00:00.000000000 +0300 >+++ oolite/files/patch-deps_mozilla_js_src_jsscript.h 2014-09-23 08:18:20.000000000 +0400 >@@ -0,0 +1,48 @@ >+# HG changeset patch >+# User Ehsan Akhgari <ehsan@mozilla.com> >+# Date 1308340787 14400 >+# Node ID c0e8643e8e60d1c98bff30c78e034f991f75c191 >+# Parent 284ebc48b2cb8e35dc04482ede700e717d8d214f >+Bug 662962 - Silence the clang warnings issued because of alignment requirements increase when compiling jsscript.h; r=Waldo >+ >+--- deps/mozilla/js/src/jsscript.h.orig 2011-04-01 06:08:36.000000000 +1100 >++++ deps/mozilla/js/src/jsscript.h 2013-05-26 00:23:16.202260566 +1000 >+@@ -496,32 +496,32 @@ >+ >+ JSObjectArray *objects() { >+ JS_ASSERT(isValidOffset(objectsOffset)); >+- return (JSObjectArray *)((uint8 *) (this + 1) + objectsOffset); >++ return reinterpret_cast<JSObjectArray *>(uintptr_t(this + 1) + objectsOffset); >+ } >+ >+ JSUpvarArray *upvars() { >+ JS_ASSERT(isValidOffset(upvarsOffset)); >+- return (JSUpvarArray *) ((uint8 *) (this + 1) + upvarsOffset); >++ return reinterpret_cast<JSUpvarArray *>(uintptr_t(this + 1) + upvarsOffset); >+ } >+ >+ JSObjectArray *regexps() { >+ JS_ASSERT(isValidOffset(regexpsOffset)); >+- return (JSObjectArray *) ((uint8 *) (this + 1) + regexpsOffset); >++ return reinterpret_cast<JSObjectArray *>(uintptr_t(this + 1) + regexpsOffset); >+ } >+ >+ JSTryNoteArray *trynotes() { >+ JS_ASSERT(isValidOffset(trynotesOffset)); >+- return (JSTryNoteArray *) ((uint8 *) (this + 1) + trynotesOffset); >++ return reinterpret_cast<JSTryNoteArray *>(uintptr_t(this + 1) + trynotesOffset); >+ } >+ >+ js::GlobalSlotArray *globals() { >+ JS_ASSERT(isValidOffset(globalsOffset)); >+- return (js::GlobalSlotArray *) ((uint8 *) (this + 1) + globalsOffset); >++ return reinterpret_cast<js::GlobalSlotArray *>(uintptr_t(this + 1) + globalsOffset); >+ } >+ >+ JSConstArray *consts() { >+ JS_ASSERT(isValidOffset(constOffset)); >+- return (JSConstArray *) ((uint8 *) (this + 1) + constOffset); >++ return reinterpret_cast<JSConstArray *>(uintptr_t(this + 1) + constOffset); >+ } >+ >+ JSAtom *getAtom(size_t index) { >diff -ruN oolite.orig/files/patch-deps_mozilla_js_src_jsstr.cpp oolite/files/patch-deps_mozilla_js_src_jsstr.cpp >--- oolite.orig/files/patch-deps_mozilla_js_src_jsstr.cpp 1970-01-01 03:00:00.000000000 +0300 >+++ oolite/files/patch-deps_mozilla_js_src_jsstr.cpp 2014-09-23 08:19:30.000000000 +0400 >@@ -0,0 +1,36 @@ >+# HG changeset patch >+# User Ehsan Akhgari <ehsan@mozilla.com> >+# Date 1308517488 14400 >+# Node ID 284ebc48b2cb8e35dc04482ede700e717d8d214f >+# Parent cecc5adfc44068fb6f11b9baa78cb5fddc100b27 >+Bug 662961 - Silence the clang warnings issued because of alignment requirements increase when compiling jsstr.cpp; r=Waldo >+ >+--- deps/mozilla/js/src/jsstr.cpp.orig 2013-05-26 00:44:33.383765764 +1000 >++++ deps/mozilla/js/src/jsstr.cpp 2013-05-26 00:46:35.842211859 +1000 >+@@ -3147,7 +3147,7 @@ >+ */ >+ #define R(c) { \ >+ BUILD_LENGTH_AND_FLAGS(1, JSString::FLAT | JSString::ATOMIZED), \ >+- { (jschar *)(((char *)(unitStringTable + (c))) + \ >++ { (jschar *)(uintptr_t(unitStringTable + (c)) + \ >+ offsetof(JSString, inlineStorage)) }, \ >+ { {(c), 0x00} } } >+ >+@@ -3207,7 +3207,7 @@ >+ */ >+ #define R(c) { \ >+ BUILD_LENGTH_AND_FLAGS(2, JSString::FLAT | JSString::ATOMIZED), \ >+- { (jschar *)(((char *)(length2StringTable + (c))) + \ >++ { (jschar *)(uintptr_t(length2StringTable + (c)) + \ >+ offsetof(JSString, inlineStorage)) }, \ >+ { {FROM_SMALL_CHAR((c) >> 6), FROM_SMALL_CHAR((c) & 0x3F), 0x00} } } >+ >+@@ -3240,7 +3240,7 @@ >+ */ >+ #define R(c) { \ >+ BUILD_LENGTH_AND_FLAGS(3, JSString::FLAT | JSString::ATOMIZED), \ >+- { (jschar *)(((char *)(hundredStringTable + ((c) - 100))) + \ >++ { (jschar *)(uintptr_t(hundredStringTable + ((c) - 100)) + \ >+ offsetof(JSString, inlineStorage)) }, \ >+ { {((c) / 100) + '0', ((c) / 10 % 10) + '0', ((c) % 10) + '0', 0x00} } } >+ >diff -ruN oolite.orig/files/patch-src_Core_NSFileManagerOOExtensions.h oolite/files/patch-src_Core_NSFileManagerOOExtensions.h >--- oolite.orig/files/patch-src_Core_NSFileManagerOOExtensions.h 2014-01-22 21:40:44.000000000 +0400 >+++ oolite/files/patch-src_Core_NSFileManagerOOExtensions.h 1970-01-01 03:00:00.000000000 +0300 >@@ -1,11 +0,0 @@ >---- src/Core/NSFileManagerOOExtensions.h.orig 2012-04-18 09:43:45.361891055 +0300 >-+++ src/Core/NSFileManagerOOExtensions.h 2012-04-18 09:44:08.916890086 +0300 >-@@ -28,7 +28,7 @@ MA 02110-1301, USA. >- >- #import <Foundation/Foundation.h> >- >--#define SAVEDIR "oolite-saves" >-+#define SAVEDIR ".oolite-saves" >- >- #if OOLITE_SDL >- #define SNAPSHOTDIR "snapshots" >diff -ruN oolite.orig/files/patch-src_Core_OOMaths.h oolite/files/patch-src_Core_OOMaths.h >--- oolite.orig/files/patch-src_Core_OOMaths.h 1970-01-01 03:00:00.000000000 +0300 >+++ oolite/files/patch-src_Core_OOMaths.h 2014-10-14 07:21:25.000000000 +0400 >@@ -0,0 +1,12 @@ >+--- src/Core/OOMaths.h.orig 2014-06-30 12:50:36.000000000 +0400 >++++ src/Core/OOMaths.h 2014-10-14 07:20:31.000000000 +0400 >+@@ -48,7 +48,8 @@ >+ #endif >+ >+ #include "OOFunctionAttributes.h" >+-#include <tgmath.h> >++#include <complex.h> >++#include <math.h> >+ #include <stdbool.h> >+ #include <stdlib.h> >+ #include <stdint.h> >diff -ruN oolite.orig/files/patch-src_Core_OOOXZManager.m oolite/files/patch-src_Core_OOOXZManager.m >--- oolite.orig/files/patch-src_Core_OOOXZManager.m 1970-01-01 03:00:00.000000000 +0300 >+++ oolite/files/patch-src_Core_OOOXZManager.m 2014-09-25 08:46:28.000000000 +0400 >@@ -0,0 +1,49 @@ >+--- src/Core/OOOXZManager.m.orig 2014-06-30 12:50:36.000000000 +0400 >++++ src/Core/OOOXZManager.m 2014-09-25 08:46:25.000000000 +0400 >+@@ -215,13 +215,45 @@ >+ } >+ if (!exists) >+ { >++#if OOLITE_MAC_OS_X >+ if (![fmgr oo_createDirectoryAtPath:path attributes:nil]) >+ { >+ OOLog(kOOOXZErrorLog, @"Could not create folder %@.", path); >+ return NO; >+ } >++#else >++ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory,NSUserDomainMask,YES); >++ NSString *appPath = [paths objectAtIndex:0]; >++ if (appPath == nil) >++ { >++ OOLog(kOOOXZErrorLog, @"Could not create folder %@.", path); >++ return NO; >++ } >++ else >++ { >++ if (![fmgr fileExistsAtPath:appPath] && ![fmgr oo_createDirectoryAtPath:appPath attributes:nil]) >++ { >++ OOLog(kOOOXZErrorLog, @"Could not create folder %@.", path); >++ return NO; >++ } >++ appPath = [appPath stringByAppendingPathComponent:@"Oolite"]; >++ if (![fmgr fileExistsAtPath:appPath] && ![fmgr oo_createDirectoryAtPath:appPath attributes:nil]) >++ { >++ OOLog(kOOOXZErrorLog, @"Could not create folder %@.", path); >++ return NO; >++ } >++ /* GNUStep uses "ApplicationSupport" rather than "Application >++ * Support" so match convention by not putting a space in the >++ * path either */ >++ appPath = [appPath stringByAppendingPathComponent:@"ManagedAddOns"]; >++ if (![fmgr fileExistsAtPath:appPath] && ![fmgr oo_createDirectoryAtPath:appPath attributes:nil]) >++ { >++ OOLog(kOOOXZErrorLog, @"Could not create folder %@.", path); >++ return NO; >++ } >++ } >++#endif >+ } >+- >+ return YES; >+ } >+ >diff -ruN oolite.orig/files/patch-src_Core_OOPointMaths.h oolite/files/patch-src_Core_OOPointMaths.h >--- oolite.orig/files/patch-src_Core_OOPointMaths.h 1970-01-01 03:00:00.000000000 +0300 >+++ oolite/files/patch-src_Core_OOPointMaths.h 2014-10-16 13:52:18.000000000 +0400 >@@ -0,0 +1,10 @@ >+--- src/Core/OOPointMaths.h.orig 2014-06-30 12:50:36.000000000 +0400 >++++ src/Core/OOPointMaths.h 2014-10-16 13:51:36.000000000 +0400 >+@@ -1,5 +1,6 @@ >+ #import "OOFunctionAttributes.h" >+-#include <tgmath.h> >++#include <complex.h> >++#include <math.h> >+ >+ >+ // Utilities for working with NSPoints as 2D vectors. >diff -ruN oolite.orig/files/pkg-message.in oolite/files/pkg-message.in >--- oolite.orig/files/pkg-message.in 2014-01-22 19:52:06.000000000 +0400 >+++ oolite/files/pkg-message.in 1970-01-01 03:00:00.000000000 +0300 >@@ -1,16 +0,0 @@ >-************************************ NOTE ************************************* >- >-If you are not a regular user of GNUstep environment, please follow these >-advice to run oolite: >- >-1. Make sure that necessary GNUstep daemons are running before starting oolite. >- Usually they are started at boot-time by %%LOCALBASE%%/etc/rc.d/GNUstep.sh >- >-2. To start the game first setup GNUstep environment and then execute >- "openapp oolite" command. >- The environment is set by doing (depending on your shell) either >- . %%PREFIX%%/System/Library/Makefiles/GNUstep.sh >- or >- source %%PREFIX%%/System/Library/Makefiles/GNUstep.csh >- >-******************************************************************************* >diff -ruN oolite.orig/pkg-descr oolite/pkg-descr >--- oolite.orig/pkg-descr 2014-01-22 19:44:51.000000000 +0400 >+++ oolite/pkg-descr 2014-09-24 09:24:30.000000000 +0400 >@@ -6,9 +6,7 @@ > The game is expandable, and numerous expansion packs already exist. New ships > and new missions are available for download. > >-You can find a first-flight tutorial here: >-http://oolite.aegidian.org/tutorial/ >+You can find the getting started page here: >+http://www.oolite.org/starting/ > >-LICENSE: CCL Attribution-Noncommercial-Share Alike 2.0 Generic >- >-WWW: http://oolite-linux.berlios.de/ >+WWW: http://www.oolite.org >diff -ruN oolite.orig/pkg-plist oolite/pkg-plist >--- oolite.orig/pkg-plist 2014-01-22 19:16:56.000000000 +0400 >+++ oolite/pkg-plist 1970-01-01 03:00:00.000000000 +0300 >@@ -1,278 +0,0 @@ >-GNUstep/Local/Applications/oolite.app/Resources/AIReference.html >-GNUstep/Local/Applications/oolite.app/Resources/AIs/buoyAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/collectLootAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/delayedReactToAttackAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/dockingAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/dumbAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/enteringPirateAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/enteringTraderAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/escortAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/exitingTraderAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/fallingShuttleAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/fttAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/gotoWaypointAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/hardMissileAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/homeAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/interceptAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/minerAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/missileAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/nullAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/oolite-constrictor-AI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/oolite-player-AI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/pirateAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/planetPatrolAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/policeInterceptAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/receiveDockingAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/risingShuttleAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/rockHermitAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/route1patrolAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/route1traderAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/route2patrolAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/route2sunskimAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/scavengerAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/stationAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/sunSkimExitAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/thargletAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/thargoidAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/timebombAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/AIs/traderInterceptAI.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/autoAImap.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/characters.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/commodities.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/crosshairs.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/customsounds.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/demoships.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/descriptions.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/equipment.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/gpu-settings.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/hud-small.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/hud.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/illegal_goods.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/javascript-errors.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/keyconfig.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/logcontrol.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/material-defaults.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/missiontext.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/nebulatextures.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/oolite-font.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/pirate-victim-roles.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/planetinfo.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/screenbackgrounds.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/script-patches.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/shipdata-overrides.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/shipdata.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/shipyard.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/speech_pronunciation_guide.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/startextures.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/verifyOXP.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/whitelist.plist >-GNUstep/Local/Applications/oolite.app/Resources/Config/world-scripts.plist >-GNUstep/Local/Applications/oolite.app/Resources/Images/WMicon.bmp >-GNUstep/Local/Applications/oolite.app/Resources/Images/oolite-long-range-chart.png >-GNUstep/Local/Applications/oolite.app/Resources/Images/oolite-nova-system.png >-GNUstep/Local/Applications/oolite.app/Resources/Images/oolite-short-range-chart.png >-GNUstep/Local/Applications/oolite.app/Resources/Images/solar.png >-GNUstep/Local/Applications/oolite.app/Resources/Images/splash.bmp >-GNUstep/Local/Applications/oolite.app/Resources/Images/splash.png >-GNUstep/Local/Applications/oolite.app/Resources/Images/trumblebox.png >-GNUstep/Local/Applications/oolite.app/Resources/Info-gnustep.plist >-GNUstep/Local/Applications/oolite.app/Resources/InfoPlist.strings >-GNUstep/Local/Applications/oolite.app/Resources/Models/adder_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/alloy.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/anaconda_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/arcdetail.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/asp_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/asteroid.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/asteroid1.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/barrel.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/boa2_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/boa_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/boulder.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/boulder1.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/buoy.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/cobra1_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/cobra1_redux1.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/cobra1_redux2.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/cobra3_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/cobra3_redux1.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/constrictor_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/dock-flat.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/dock.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/escpod_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/ferdelance_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/gecko_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/krait_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/mamba_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/mamba_redux1.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/missile.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/moray_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/moray_redux1.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/new-dodo.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/new-icos.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/new-rock.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/new_coriolis.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/oolite-ball-turret.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/oolite-unknown-ship.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/python_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/python_redux1.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/python_redux2.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/qbomb.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/ring.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/rock-box.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/rock-dock.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/scarred_alloy.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/shuttle_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/sidewinder_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/splinter.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/splinter1.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/strut.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/thargoid_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/thargon_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/transporter_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/transporter_redux1.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/viper_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/viperi_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/worm_redux.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/worm_redux1.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/wreck1.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/wreck2.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/wreck3.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/wreck4.dat >-GNUstep/Local/Applications/oolite.app/Resources/Models/wreck5.dat >-GNUstep/Local/Applications/oolite.app/Resources/Music/BlueDanube.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Music/OoliteTheme.ogg >-GNUstep/Local/Applications/oolite.app/Resources/README.TXT >-GNUstep/Local/Applications/oolite.app/Resources/Schemata/README.txt >-GNUstep/Local/Applications/oolite.app/Resources/Schemata/demoshipsSchema.plist >-GNUstep/Local/Applications/oolite.app/Resources/Schemata/hudSchema.plist >-GNUstep/Local/Applications/oolite.app/Resources/Schemata/plistschema.plist >-GNUstep/Local/Applications/oolite.app/Resources/Schemata/shipdataEntrySchema.plist >-GNUstep/Local/Applications/oolite.app/Resources/Schemata/shipyardSchema.plist >-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-cloaking-device-mission.js >-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-cloaking-device-pod.js >-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-cloaking-device-target-ship.js >-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-constrictor-hunt-mission.js >-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-constrictor-pilot.js >-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-constrictor.js >-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-default-player-script.js >-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-default-ship-script.js >-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-global-prefix.js >-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-locale-functions.js >-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-nova-mission.js >-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-thargoid-plans-mission.js >-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-thargoid-warship.js >-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-trumbles-mission.js >-GNUstep/Local/Applications/oolite.app/Resources/Shaders/oolite-default-shader.fragment >-GNUstep/Local/Applications/oolite.app/Resources/Shaders/oolite-dust.fragment >-GNUstep/Local/Applications/oolite.app/Resources/Shaders/oolite-dust.vertex >-GNUstep/Local/Applications/oolite.app/Resources/Shaders/oolite-standard-vertex.vertex >-GNUstep/Local/Applications/oolite.app/Resources/Shaders/oolite-tangent-space-vertex.vertex >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/afterburner1.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/beep.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/bigbang.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/boop.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/breakpattern.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/buy.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/ecm.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/guiclick.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/hit.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/hullbang.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/laser.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/laserhits.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/missile.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/scoop.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/sell.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/trumble.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/trumblesqueal.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/warning.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Sounds/witchabort.ogg >-GNUstep/Local/Applications/oolite.app/Resources/Textures/MorayMED_bottom.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/MorayMED_top.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/adder_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/anaconda_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/arcdetail.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/asp_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/asteroid.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/back_metal.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/barrel_metal.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/boa2_left.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/boa2_rear.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/boa2_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/boa2_right.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/boa2_top.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/boa_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/bottom_metal.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/cobra1_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/cobra1_redux1.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/cobra1_redux2.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/cobra1miner_top.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/cobra3_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/cobra3_redux1.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/constrictor_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/dark_metal.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/ferdelance_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/front_metal.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/galaxy256.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/gecko_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/krait_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/left_metal.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/mamba_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/mamba_redux1.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/metal.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/missile.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/moray_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/moray_redux1.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-ball-turret.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-barrel-specular.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-document.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-expansion-document.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-font.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-logo1.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-nebula-1.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-nebula-2.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-nebula-3.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-nebula-4.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-particle-blur.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-particle-flash.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-scarred-metal-specular.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-star-1.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/pod2_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/python_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/python_redux1.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/python_redux2.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/qbomb.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/right_metal.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/scarred_metal.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/shuttle_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/sidewinder_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/star64.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/target_metal.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/thargoid_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/thargon_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/top_metal.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/transporter_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/transporter_redux1.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/trumblekit.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/viper_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/viperi_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/worm_redux.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/worm_redux1.png >-GNUstep/Local/Applications/oolite.app/Resources/Textures/wreck.png >-GNUstep/Local/Applications/oolite.app/Resources/oolite-document.icns >-GNUstep/Local/Applications/oolite.app/Resources/oolite-expansion-document.icns >-GNUstep/Local/Applications/oolite.app/Resources/oolite-icon.icns >-GNUstep/Local/Applications/oolite.app/oolite >-share/applications/oolite.desktop >-share/pixmaps/oolite-icon.png >-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Textures >-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Sounds >-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Shaders >-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Scripts >-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Schemata >-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Music >-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Models >-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Images >-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Config >-@dirrm GNUstep/Local/Applications/oolite.app/Resources/AIs >-@dirrm GNUstep/Local/Applications/oolite.app/Resources >-@dirrm GNUstep/Local/Applications/oolite.app
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 193886
:
147632
|
147633
|
147660
|
147661
|
148273
|
148274
|
148275
|
148276
|
148287
|
148288
|
148289
|
148367
|
148368
|
148391
|
148444
|
148445
|
148446
|
148447
|
148477
|
148551
|
148552
| 148570 |
148571