Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 //===- subzero/src/IceBrowserCompileServer.cpp - Browser Compile server ---===// | |
| 2 // | |
| 3 // The Subzero Code Generator | |
| 4 // | |
| 5 // This file is distributed under the University of Illinois Open Source | |
| 6 // License. See LICENSE.TXT for details. | |
| 7 // | |
| 8 //===----------------------------------------------------------------------===// | |
| 9 // | |
| 10 // This file defines the browser-based compile server. | |
| 11 // | |
| 12 //===----------------------------------------------------------------------===// | |
| 13 | |
| 14 // Can only compile this with the NaCl compiler (needs irt.h, and the | |
| 15 // unsandboxed LLVM build using the trusted compiler does not have irt.h). | |
| 16 #if PNACL_BROWSER_TRANSLATOR | |
| 17 | |
| 18 #include "IceBrowserCompileServer.h" | |
|
Jim Stichnoth
2015/03/13 04:55:00
Move after llvm/ includes?
jvoung (off chromium)
2015/03/18 15:39:09
Done.
Oops, I got mixed up with some other coding
| |
| 19 | |
| 20 #include <argz.h> | |
| 21 #include <cstring> | |
| 22 #include <cstdlib> | |
| 23 #include <thread> | |
| 24 | |
| 25 #include "llvm/Support/FileSystem.h" | |
| 26 #include "llvm/Support/raw_os_ostream.h" | |
|
Jim Stichnoth
2015/03/13 04:55:00
sort these includes
jvoung (off chromium)
2015/03/18 15:39:09
Done.
| |
| 27 #include "llvm/Support/QueueStreamer.h" | |
| 28 | |
| 29 #include <irt.h> | |
|
jvoung (off chromium)
2015/03/18 15:39:09
I moved these to be with the other <...> includes.
| |
| 30 #include <irt_dev.h> | |
| 31 | |
| 32 namespace Ice { | |
| 33 | |
| 34 // Create C wrappers around callback handlers for the IRT interface. | |
| 35 namespace { | |
| 36 | |
| 37 struct nacl_irt_private_pnacl_translator_subzero gIRTTranslatorSubzero; | |
| 38 BrowserCompileServer *gCompileServer; | |
| 39 | |
| 40 void getIRTInterfaces() { | |
| 41 size_t query_result = nacl_interface_query( | |
| 42 NACL_IRT_PRIVATE_PNACL_TRANSLATOR_SUBZERO_v0_1, &gIRTTranslatorSubzero, | |
| 43 sizeof(gIRTTranslatorSubzero)); | |
| 44 if (query_result != sizeof(gIRTTranslatorSubzero)) | |
| 45 llvm::report_fatal_error("Failed to get translator_subzero IRT interface"); | |
| 46 } | |
| 47 | |
| 48 int onInitCallback(uint32_t NumThreads, int ObjFileFD, const char *CmdFlags, | |
| 49 size_t CmdFlagsLen) { | |
| 50 (void)NumThreads; | |
| 51 std::vector<char *> CmdFlagList; | |
| 52 // Push some dummy arguments for the program name, input file, and | |
| 53 // output file to satisfy the argument parser and the sanity checks | |
| 54 // (e.g., never write ELF binary to stdout). | |
| 55 // We also always do binary output, so set that as the default. | |
| 56 CmdFlagList.push_back(strdup("pnacl-sz")); | |
| 57 CmdFlagList.push_back(strdup("browser_input.pexe")); | |
| 58 CmdFlagList.push_back(strdup("-o=browser_output.o")); | |
| 59 CmdFlagList.push_back(strdup("-filetype=obj")); | |
| 60 // TODO(jvoung): Make sure we don't send unnecessary arguments | |
| 61 // like -split-module=N. | |
| 62 IceString ThreadStrBuffer; | |
| 63 llvm::raw_string_ostream ThreadStr(ThreadStrBuffer); | |
| 64 ThreadStr << "-threads=" << NumThreads; | |
| 65 CmdFlagList.push_back(strdup(ThreadStr.str().c_str())); | |
| 66 const char *NextEntry = CmdFlags; | |
| 67 while (NextEntry != nullptr && CmdFlagsLen) { | |
| 68 // Make a copy of each null-terminated segment, since the | |
| 69 // incoming string is owned by the caller. | |
| 70 CmdFlagList.push_back(strdup(NextEntry)); | |
| 71 // re: const cast -- the string pointed-to by each "NextEntry" is | |
| 72 // ultimately strdup'ed so the original won't be modified. | |
| 73 NextEntry = argz_next(const_cast<char *>(CmdFlags), CmdFlagsLen, NextEntry); | |
| 74 } | |
| 75 // Make an argv array from the input vector. | |
| 76 size_t argc = CmdFlagList.size(); | |
| 77 char **argv = new char *[argc + 1]; | |
| 78 for (size_t i = 0; i < argc; ++i) { | |
| 79 argv[i] = CmdFlagList[i]; | |
| 80 } | |
| 81 argv[argc] = nullptr; | |
| 82 gCompileServer->takeArgs(static_cast<int>(argc), argv); | |
| 83 gCompileServer->setOutputFD(ObjFileFD); | |
| 84 gCompileServer->startCompileThread(); | |
| 85 return gCompileServer->getReturnValue(); | |
| 86 } | |
| 87 | |
| 88 int onDataCallback(unsigned char *Data, size_t NumBytes) { | |
| 89 return gCompileServer->pushInputBytes(Data, NumBytes) ? 1 : 0; | |
| 90 } | |
| 91 | |
| 92 int onEndCallback() { | |
| 93 gCompileServer->endInputStream(); | |
| 94 gCompileServer->waitForCompileThread(); | |
| 95 // TODO(jvoung): Also return an error string, and UMA data. | |
| 96 // Set up a report_fatal_error handler to grab that string. | |
| 97 return gCompileServer->getReturnValue(); | |
| 98 } | |
| 99 | |
| 100 struct PNaClSubzeroFunctions SubzeroCallbacks { | |
| 101 &onInitCallback, &onDataCallback, &onEndCallback | |
| 102 }; | |
| 103 | |
| 104 } // end of anonymous namespace | |
| 105 | |
| 106 BrowserCompileServer::~BrowserCompileServer() { | |
| 107 // strings were strdup'ed so free instead of delete. | |
| 108 for (int i = 0; i < argc; ++i) | |
| 109 free(argv[i]); | |
| 110 delete[] argv; | |
| 111 } | |
| 112 | |
| 113 void BrowserCompileServer::run() { | |
| 114 gCompileServer = this; | |
| 115 getIRTInterfaces(); | |
| 116 gIRTTranslatorSubzero.serve_translate_request(&SubzeroCallbacks); | |
| 117 } | |
| 118 | |
| 119 std::unique_ptr<llvm::DataStreamer> | |
| 120 BrowserCompileServer::getInputStream(const IceString &InputFilename, | |
| 121 std::string &ErrorString) { | |
| 122 // There is no real filename / and there should be no error. | |
| 123 (void)InputFilename; | |
| 124 (void)ErrorString; | |
| 125 std::unique_ptr<llvm::QueueStreamer> Result(new llvm::QueueStreamer()); | |
| 126 InputStream = Result.get(); | |
| 127 return std::move(Result); | |
| 128 } | |
| 129 | |
| 130 std::unique_ptr<llvm::raw_fd_ostream> | |
| 131 BrowserCompileServer::getOutputStream(const IceString &OutputFilename, | |
| 132 std::error_code &EC) { | |
| 133 // There is no real filename / and there should be no error | |
| 134 // since the fd is already opened. | |
| 135 (void)OutputFilename; | |
| 136 (void)EC; | |
| 137 if (OutputFD <= 0) | |
| 138 llvm::report_fatal_error("Invalid output FD"); | |
| 139 const bool CloseOnDtor = true; | |
| 140 const bool Unbuffered = false; | |
| 141 std::unique_ptr<llvm::raw_fd_ostream> Result( | |
| 142 new llvm::raw_fd_ostream(OutputFD, CloseOnDtor, Unbuffered)); | |
| 143 OutputFD = -1; | |
| 144 return std::move(Result); | |
| 145 } | |
| 146 | |
| 147 bool BrowserCompileServer::pushInputBytes(unsigned char *Data, | |
| 148 size_t NumBytes) { | |
| 149 return InputStream->PutBytes(Data, NumBytes) != NumBytes; | |
| 150 } | |
| 151 | |
| 152 void BrowserCompileServer::endInputStream() { return InputStream->SetDone(); } | |
| 153 | |
| 154 void BrowserCompileServer::startCompileThread() { | |
| 155 CompileThread = | |
| 156 std::thread([this]() { this->getCompiler().run(argc, argv, *this); }); | |
| 157 } | |
| 158 | |
| 159 } // end of namespace Ice | |
| 160 | |
| 161 #endif // PNACL_BROWSER_TRANSLATOR | |
| OLD | NEW |