From 87f03108f282a9b5f172f91679bd89ddbb5a65be Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 26 Dec 2003 06:50:30 +0000 Subject: [PATCH] Factor code out of LLI git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10616 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/ExecutionEngine/ExecutionEngine.cpp | 54 +++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index c820f63c29f..bb52c943111 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -46,6 +46,60 @@ ExecutionEngine::~ExecutionEngine() { delete MP; } + +// CreateArgv - Turn a vector of strings into a nice argv style array of +// pointers to null terminated strings. +// +static void *CreateArgv(ExecutionEngine *EE, + const std::vector &InputArgv) { + unsigned PtrSize = EE->getTargetData().getPointerSize(); + char *Result = new char[(InputArgv.size()+1)*PtrSize]; + + DEBUG(std::cerr << "ARGV = " << (void*)Result << "\n"); + const Type *SBytePtr = PointerType::get(Type::SByteTy); + + for (unsigned i = 0; i != InputArgv.size(); ++i) { + unsigned Size = InputArgv[i].size()+1; + char *Dest = new char[Size]; + DEBUG(std::cerr << "ARGV[" << i << "] = " << (void*)Dest << "\n"); + + std::copy(InputArgv[i].begin(), InputArgv[i].end(), Dest); + Dest[Size-1] = 0; + + // Endian safe: Result[i] = (PointerTy)Dest; + EE->StoreValueToMemory(PTOGV(Dest), (GenericValue*)(Result+i*PtrSize), + SBytePtr); + } + + // Null terminate it + EE->StoreValueToMemory(PTOGV(0), + (GenericValue*)(Result+InputArgv.size()*PtrSize), + SBytePtr); + return Result; +} + +/// runFunctionAsMain - This is a helper function which wraps runFunction to +/// handle the common task of starting up main with the specified argc, argv, +/// and envp parameters. +int ExecutionEngine::runFunctionAsMain(Function *Fn, + const std::vector &argv, + const char * const * envp) { + std::vector GVArgs; + GenericValue GVArgc; + GVArgc.IntVal = argv.size(); + GVArgs.push_back(GVArgc); // Arg #0 = argc. + GVArgs.push_back(PTOGV(CreateArgv(this, argv))); // Arg #1 = argv. + assert(((char **)GVTOP(GVArgs[1]))[0] && "argv[0] was null after CreateArgv"); + + std::vector EnvVars; + for (unsigned i = 0; envp[i]; ++i) + EnvVars.push_back(envp[i]); + GVArgs.push_back(PTOGV(CreateArgv(this, EnvVars))); // Arg #2 = envp. + return runFunction(Fn, GVArgs).IntVal; +} + + + /// If possible, create a JIT, unless the caller specifically requests an /// Interpreter or there's an error. If even an Interpreter cannot be created, /// NULL is returned.