void* Interpreter::compileFunction(llvm::StringRef name, llvm::StringRef code, bool ifUnique, bool withAccessControl) { // // Compile the wrapper code. // const llvm::GlobalValue* GV = 0; if (isInSyntaxOnlyMode()) return 0; if (ifUnique) GV = getLastTransaction()->getModule()->getNamedValue(name); if (!GV) { const FunctionDecl* FD = DeclareCFunction(name, code, withAccessControl); if (!FD) return 0; // // Get the wrapper function pointer // from the ExecutionEngine (the JIT). // GV = getLastTransaction()->getModule()->getNamedValue(name); } if (!GV) return 0; return m_Executor->getPointerToGlobalFromJIT(*GV); }
void IncrementalParser::addTransaction(Transaction* T) { if (!T->isNestedTransaction() && T != getLastTransaction()) { if (getLastTransaction()) m_Transactions.back()->setNext(T); m_Transactions.push_back(T); } }
void* Interpreter::getAddressOfGlobal(llvm::StringRef SymName, bool* fromJIT /*=0*/) const { // Return a symbol's address, and whether it was jitted. if (isInSyntaxOnlyMode()) return 0; llvm::Module* module = getLastTransaction()->getModule(); return m_Executor->getAddressOfGlobal(module, SymName, fromJIT); }
Transaction* IncrementalParser::beginTransaction(const CompilationOptions& Opts) { Transaction* OldCurT = m_Consumer->getTransaction(); Transaction* NewCurT = 0; // If we are in the middle of transaction and we see another begin // transaction - it must be nested transaction. if (OldCurT && OldCurT->getState() <= Transaction::kCommitting) { // If the last nested was empty just reuse it. Transaction* LastNestedT = OldCurT->getLastNestedTransaction(); if (LastNestedT && LastNestedT->empty()) { assert(LastNestedT->getState() == Transaction::kCommitted && "Broken"); NewCurT = LastNestedT; NewCurT->reset(); NewCurT->setCompilationOpts(Opts); } else { NewCurT = new Transaction(Opts); OldCurT->addNestedTransaction(NewCurT); // takes the ownership } m_Consumer->setTransaction(NewCurT); return NewCurT; } if (getLastTransaction() && getLastTransaction()->empty()) { NewCurT = getLastTransaction(); NewCurT->reset(); NewCurT->setCompilationOpts(Opts); } else NewCurT = new Transaction(Opts); m_Consumer->setTransaction(NewCurT); if (!m_FirstTransaction) { m_FirstTransaction = NewCurT; m_LastTransaction = NewCurT; } else if (NewCurT != m_LastTransaction){ m_LastTransaction->setNext(NewCurT); m_LastTransaction = NewCurT; // takes the ownership } return NewCurT; }
void IncrementalParser::unloadTransaction(Transaction* T) { if (!T) T = getLastTransaction(); assert(T->getState() == Transaction::kCommitted && "Unloading not commited transaction?"); assert(T->getModule() && "Trying to uncodegen transaction taken in syntax only mode. "); ASTNodeEraser NodeEraser(&getCI()->getSema()); NodeEraser.RevertTransaction(T); InterpreterCallbacks* callbacks = m_Interpreter->getCallbacks(); if (callbacks) callbacks->TransactionUnloaded(*T); }
// Add the input to the memory buffer, parse it, and add it to the AST. IncrementalParser::EParseResult IncrementalParser::Parse(llvm::StringRef input) { Preprocessor& PP = m_CI->getPreprocessor(); DiagnosticConsumer& DClient = m_CI->getDiagnosticClient(); PP.enableIncrementalProcessing(); DClient.BeginSourceFile(m_CI->getLangOpts(), &PP); // Reset the transaction information getLastTransaction().setBeforeFirstDecl(getCI()->getSema().CurContext); if (input.size()) { std::ostringstream source_name; source_name << "input_line_" << (m_MemoryBuffer.size() + 1); llvm::MemoryBuffer* MB = llvm::MemoryBuffer::getMemBufferCopy(input, source_name.str()); m_MemoryBuffer.push_back(MB); SourceManager& SM = getCI()->getSourceManager(); // Create SourceLocation, which will allow clang to order the overload // candidates for example SourceLocation NewLoc = SM.getLocForStartOfFile(m_VirtualFileID); NewLoc = NewLoc.getLocWithOffset(m_MemoryBuffer.size() + 1); // Create FileID for the current buffer FileID FID = SM.createFileIDForMemBuffer(m_MemoryBuffer.back(), /*LoadedID*/0, /*LoadedOffset*/0, NewLoc); PP.EnterSourceFile(FID, 0, NewLoc); } Parser::DeclGroupPtrTy ADecl; while (!m_Parser->ParseTopLevelDecl(ADecl)) { // Not end of file. // If we got a null return and something *was* parsed, ignore it. This // is due to a top-level semicolon, an action override, or a parse error // skipping something. if (ADecl) { DeclGroupRef DGR = ADecl.getAsVal<DeclGroupRef>(); for (DeclGroupRef::iterator i=DGR.begin(); i< DGR.end(); ++i) { if (!m_FirstTopLevelDecl) m_FirstTopLevelDecl = *((*i)->getDeclContext()->decls_begin()); m_LastTopLevelDecl = *i; } m_Consumer->HandleTopLevelDecl(DGR); } // ADecl }; // Process any TopLevelDecls generated by #pragma weak. for (llvm::SmallVector<Decl*,2>::iterator I = getCI()->getSema().WeakTopLevelDecls().begin(), E = getCI()->getSema().WeakTopLevelDecls().end(); I != E; ++I) { m_Consumer->HandleTopLevelDecl(DeclGroupRef(*I)); } getCI()->getSema().PerformPendingInstantiations(); DClient.EndSourceFile(); PP.enableIncrementalProcessing(false); DiagnosticsEngine& Diag = getCI()->getSema().getDiagnostics(); if (Diag.hasErrorOccurred()) return IncrementalParser::kFailed; else if (Diag.getNumWarnings()) return IncrementalParser::kSuccessWithWarnings; return IncrementalParser::kSuccess; }
void Interpreter::AddAtExitFunc(void (*Func) (void*), void* Arg) { m_Executor->AddAtExitFunc(Func, Arg, getLastTransaction()); }