Refactor Subzero initialization and add a browser callback handler.

Handlers are represented as a "compile server" even though
right now it can really only handle a single
compile request.

Then there can be a commandline-based server and a
browser-based server. This server takes over the main
thread. In the browser-based case the server can block,
waiting on bytes to be pushed. This becomes a producer of
bitcode bytes.

The original main thread which did bitcode reading is now
shifted to yet another worker thread, which is then the
consumer of bitcode bytes.

This uses an IRT interface for listening to messages
from the browser:
https://codereview.chromium.org/984713003/

TEST=Build the IRT core nexe w/ the above patch and compile w/ something like:

echo """
readwrite_file objfile /tmp/temp.nexe---gcc.opt.stripped.pexe---.o
rpc StreamInitWithSplit i(4) h(objfile) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) C(4,-O2\x00) * s()
stream_file /usr/local/google/home/jvoung/pexe_tests/gcc.opt.stripped.pexe 65536 1000000000
rpc StreamEnd * i() s() s() s()
echo "pnacl-sz complete"
""" | scons-out/opt-linux-x86-32/staging/sel_universal \
    -a -B scons-out/nacl_irt-x86-32/staging/irt_core.nexe \
    --abort_on_error \
    -- toolchain/linux_x86/pnacl_translator/translator/x86-32/bin/pnacl-sz.nexe

echo """
readwrite_file nexefile /tmp/temp.nexe.tmp
readonly_file objfile0 /tmp/temp.nexe---gcc.opt.stripped.pexe---.o
rpc RunWithSplit i(1) h(objfile0) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(invalid) h(nexefile) *
echo "ld complete"
""" | /usr/local/google/home/nacl3/native_client/scons-out/opt-linux-x86-32/staging/sel_universal \
    --abort_on_error \
    -a -B \
    scons-out/nacl_irt-x86-32/staging/irt_core.nexe \
    -E NACL_IRT_OPEN_RESOURCE_BASE=toolchain/linux_x86/pnacl_translator/translator/x86-32/lib/ \
    -E NACL_IRT_OPEN_RESOURCE_REMAP=libpnacl_irt_shim.a:libpnacl_irt_shim_dummy.a \
    -- toolchain/linux_x86/pnacl_translator/translator/x86-32/bin/ld.nexe

BUG= https://code.google.com/p/nativeclient/issues/detail?id=4091
R=kschimpf@google.com, stichnot@chromium.org

Review URL: https://codereview.chromium.org/997773002
diff --git a/src/IceBrowserCompileServer.h b/src/IceBrowserCompileServer.h
new file mode 100644
index 0000000..034a1af
--- /dev/null
+++ b/src/IceBrowserCompileServer.h
@@ -0,0 +1,95 @@
+//===- subzero/src/IceBrowserCompileServer.h - Browser server ---*- C++ -*-===//
+//
+//                        The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the browser-specific compile server.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUBZERO_SRC_ICEBROWSERCOMPILESERVER_H
+#define SUBZERO_SRC_ICEBROWSERCOMPILESERVER_H
+
+#include <thread>
+
+#include "IceClFlags.h"
+#include "IceClFlagsExtra.h"
+#include "IceCompileServer.h"
+#include "IceDefs.h"
+#include "IceELFStreamer.h"
+
+namespace llvm {
+class QueueStreamer;
+class raw_fd_ostream;
+};
+
+namespace Ice {
+
+// The browser variant of the compile server.
+// Compared to the commandline version, this version gets compile
+// requests over IPC. Each compile request will have a slimmed down
+// version of argc, argv while other flags are set to defaults that
+// make sense in the browser case. The output file is specified via
+// a posix FD, and input bytes are pushed to the server.
+class BrowserCompileServer : public CompileServer {
+  BrowserCompileServer() = delete;
+  BrowserCompileServer(const BrowserCompileServer &) = delete;
+  BrowserCompileServer &operator=(const BrowserCompileServer &) = delete;
+
+public:
+  explicit BrowserCompileServer(Compiler &Comp)
+      : CompileServer(Comp), InputStream(nullptr) {}
+
+  ~BrowserCompileServer() final;
+
+  void run() final;
+
+  // Parse and set up the flags for compile jobs.
+  void getParsedFlags(uint32_t NumThreads, int argc, char **argv);
+
+  // Creates the streams + context and starts the compile thread,
+  // handing off the streams + context.
+  void startCompileThread(int OutFD);
+
+  // Call to push more bytes to the current input stream.
+  // Returns false on success and true on error.
+  bool pushInputBytes(const void *Data, size_t NumBytes);
+
+  // Notify the input stream of EOF.
+  void endInputStream();
+
+  // Wait for the compile thread to complete then reset the state.
+  void waitForCompileThread() {
+    CompileThread.join();
+    LastError.assign(Ctx->getErrorStatus()->value());
+    // Reset some state. The InputStream is deleted by the compiler
+    // so only reset this to nullptr. Free and flush the rest
+    // of the streams.
+    InputStream = nullptr;
+    EmitStream.reset(nullptr);
+    ELFStream.reset(nullptr);
+  }
+
+private:
+  // This currently only handles a single compile request, hence one copy
+  // of the state.
+  std::unique_ptr<GlobalContext> Ctx;
+  // A borrowed reference to the current InputStream. The compiler owns
+  // the actual reference so the server must be careful not to access
+  // after the compiler is done.
+  llvm::QueueStreamer *InputStream;
+  std::unique_ptr<Ostream> LogStream;
+  std::unique_ptr<llvm::raw_fd_ostream> EmitStream;
+  std::unique_ptr<ELFStreamer> ELFStream;
+  ClFlags Flags;
+  ClFlagsExtra ExtraFlags;
+  std::thread CompileThread;
+};
+
+} // end of namespace Ice
+
+#endif // SUBZERO_SRC_ICEBROWSERCOMPILESERVER_H