1221345Sdim//===-- MCJIT.cpp - MC-based Just-in-Time Compiler ------------------------===//
2218885Sdim//
3218885Sdim//                     The LLVM Compiler Infrastructure
4218885Sdim//
5218885Sdim// This file is distributed under the University of Illinois Open Source
6218885Sdim// License. See LICENSE.TXT for details.
7218885Sdim//
8218885Sdim//===----------------------------------------------------------------------===//
9218885Sdim
10218885Sdim#include "MCJIT.h"
11218885Sdim#include "llvm/ExecutionEngine/GenericValue.h"
12245431Sdim#include "llvm/ExecutionEngine/JITEventListener.h"
13245431Sdim#include "llvm/ExecutionEngine/JITMemoryManager.h"
14218885Sdim#include "llvm/ExecutionEngine/MCJIT.h"
15245431Sdim#include "llvm/ExecutionEngine/ObjectBuffer.h"
16245431Sdim#include "llvm/ExecutionEngine/ObjectImage.h"
17263509Sdim#include "llvm/PassManager.h"
18252723Sdim#include "llvm/ExecutionEngine/SectionMemoryManager.h"
19252723Sdim#include "llvm/IR/DataLayout.h"
20252723Sdim#include "llvm/IR/DerivedTypes.h"
21252723Sdim#include "llvm/IR/Function.h"
22263509Sdim#include "llvm/IR/Module.h"
23221345Sdim#include "llvm/MC/MCAsmInfo.h"
24252723Sdim#include "llvm/Support/DynamicLibrary.h"
25218885Sdim#include "llvm/Support/ErrorHandling.h"
26221345Sdim#include "llvm/Support/MemoryBuffer.h"
27245431Sdim#include "llvm/Support/MutexGuard.h"
28218885Sdim
29218885Sdimusing namespace llvm;
30218885Sdim
31218885Sdimnamespace {
32218885Sdim
33218885Sdimstatic struct RegisterJIT {
34218885Sdim  RegisterJIT() { MCJIT::Register(); }
35218885Sdim} JITRegistrator;
36218885Sdim
37218885Sdim}
38218885Sdim
39218885Sdimextern "C" void LLVMLinkInMCJIT() {
40218885Sdim}
41218885Sdim
42218885SdimExecutionEngine *MCJIT::createJIT(Module *M,
43218885Sdim                                  std::string *ErrorStr,
44263509Sdim                                  RTDyldMemoryManager *MemMgr,
45218885Sdim                                  bool GVsWithCode,
46223017Sdim                                  TargetMachine *TM) {
47218885Sdim  // Try to register the program as a source of symbols to resolve against.
48218885Sdim  //
49218885Sdim  // FIXME: Don't do this here.
50218885Sdim  sys::DynamicLibrary::LoadLibraryPermanently(0, NULL);
51218885Sdim
52263509Sdim  return new MCJIT(M, TM, MemMgr ? MemMgr : new SectionMemoryManager(),
53263509Sdim                   GVsWithCode);
54245431Sdim}
55218885Sdim
56245431SdimMCJIT::MCJIT(Module *m, TargetMachine *tm, RTDyldMemoryManager *MM,
57245431Sdim             bool AllocateGVsWithCode)
58263509Sdim  : ExecutionEngine(m), TM(tm), Ctx(0), MemMgr(this, MM), Dyld(&MemMgr),
59263509Sdim    ObjCache(0) {
60245431Sdim
61263509Sdim  OwnedModules.addModule(m);
62245431Sdim  setDataLayout(TM->getDataLayout());
63218885Sdim}
64218885Sdim
65245431SdimMCJIT::~MCJIT() {
66263509Sdim  MutexGuard locked(lock);
67263509Sdim  // FIXME: We are managing our modules, so we do not want the base class
68263509Sdim  // ExecutionEngine to manage them as well. To avoid double destruction
69263509Sdim  // of the first (and only) module added in ExecutionEngine constructor
70263509Sdim  // we remove it from EE and will destruct it ourselves.
71263509Sdim  //
72263509Sdim  // It may make sense to move our module manager (based on SmallStPtr) back
73263509Sdim  // into EE if the JIT and Interpreter can live with it.
74263509Sdim  // If so, additional functions: addModule, removeModule, FindFunctionNamed,
75263509Sdim  // runStaticConstructorsDestructors could be moved back to EE as well.
76263509Sdim  //
77263509Sdim  Modules.clear();
78263509Sdim  Dyld.deregisterEHFrames();
79263509Sdim
80263509Sdim  LoadedObjectMap::iterator it, end = LoadedObjects.end();
81263509Sdim  for (it = LoadedObjects.begin(); it != end; ++it) {
82263509Sdim    ObjectImage *Obj = it->second;
83263509Sdim    if (Obj) {
84263509Sdim      NotifyFreeingObject(*Obj);
85263509Sdim      delete Obj;
86263509Sdim    }
87263509Sdim  }
88263509Sdim  LoadedObjects.clear();
89245431Sdim  delete TM;
90245431Sdim}
91221345Sdim
92263509Sdimvoid MCJIT::addModule(Module *M) {
93263509Sdim  MutexGuard locked(lock);
94263509Sdim  OwnedModules.addModule(M);
95263509Sdim}
96263509Sdim
97263509Sdimbool MCJIT::removeModule(Module *M) {
98263509Sdim  MutexGuard locked(lock);
99263509Sdim  return OwnedModules.removeModule(M);
100263509Sdim}
101263509Sdim
102263509Sdim
103263509Sdim
104252723Sdimvoid MCJIT::setObjectCache(ObjectCache* NewCache) {
105263509Sdim  MutexGuard locked(lock);
106252723Sdim  ObjCache = NewCache;
107252723Sdim}
108252723Sdim
109263509SdimObjectBufferStream* MCJIT::emitObject(Module *M) {
110245431Sdim  MutexGuard locked(lock);
111245431Sdim
112263509Sdim  // This must be a module which has already been added but not loaded to this
113263509Sdim  // MCJIT instance, since these conditions are tested by our caller,
114263509Sdim  // generateCodeForModule.
115245431Sdim
116245431Sdim  PassManager PM;
117245431Sdim
118245431Sdim  PM.add(new DataLayout(*TM->getDataLayout()));
119245431Sdim
120245431Sdim  // The RuntimeDyld will take ownership of this shortly
121252723Sdim  OwningPtr<ObjectBufferStream> CompiledObject(new ObjectBufferStream());
122245431Sdim
123221345Sdim  // Turn the machine code intermediate representation into bytes in memory
124221345Sdim  // that may be executed.
125252723Sdim  if (TM->addPassesToEmitMC(PM, Ctx, CompiledObject->getOStream(), false)) {
126221345Sdim    report_fatal_error("Target does not support MC emission!");
127221345Sdim  }
128221345Sdim
129221345Sdim  // Initialize passes.
130263509Sdim  PM.run(*M);
131245431Sdim  // Flush the output buffer to get the generated code into memory
132252723Sdim  CompiledObject->flush();
133221345Sdim
134252723Sdim  // If we have an object cache, tell it about the new object.
135252723Sdim  // Note that we're using the compiled image, not the loaded image (as below).
136252723Sdim  if (ObjCache) {
137252723Sdim    // MemoryBuffer is a thin wrapper around the actual memory, so it's OK
138252723Sdim    // to create a temporary object here and delete it after the call.
139252723Sdim    OwningPtr<MemoryBuffer> MB(CompiledObject->getMemBuffer());
140263509Sdim    ObjCache->notifyObjectCompiled(M, MB.get());
141252723Sdim  }
142252723Sdim
143252723Sdim  return CompiledObject.take();
144252723Sdim}
145252723Sdim
146263509Sdimvoid MCJIT::generateCodeForModule(Module *M) {
147252723Sdim  // Get a thread lock to make sure we aren't trying to load multiple times
148252723Sdim  MutexGuard locked(lock);
149252723Sdim
150263509Sdim  // This must be a module which has already been added to this MCJIT instance.
151263509Sdim  assert(OwnedModules.ownsModule(M) &&
152263509Sdim         "MCJIT::generateCodeForModule: Unknown module.");
153263509Sdim
154252723Sdim  // Re-compilation is not supported
155263509Sdim  if (OwnedModules.hasModuleBeenLoaded(M))
156252723Sdim    return;
157252723Sdim
158252723Sdim  OwningPtr<ObjectBuffer> ObjectToLoad;
159252723Sdim  // Try to load the pre-compiled object from cache if possible
160252723Sdim  if (0 != ObjCache) {
161263509Sdim    OwningPtr<MemoryBuffer> PreCompiledObject(ObjCache->getObject(M));
162252723Sdim    if (0 != PreCompiledObject.get())
163252723Sdim      ObjectToLoad.reset(new ObjectBuffer(PreCompiledObject.take()));
164252723Sdim  }
165252723Sdim
166252723Sdim  // If the cache did not contain a suitable object, compile the object
167252723Sdim  if (!ObjectToLoad) {
168252723Sdim    ObjectToLoad.reset(emitObject(M));
169252723Sdim    assert(ObjectToLoad.get() && "Compilation did not produce an object.");
170252723Sdim  }
171252723Sdim
172221345Sdim  // Load the object into the dynamic linker.
173263509Sdim  // MCJIT now owns the ObjectImage pointer (via its LoadedObjects map).
174263509Sdim  ObjectImage *LoadedObject = Dyld.loadObject(ObjectToLoad.take());
175263509Sdim  LoadedObjects[M] = LoadedObject;
176245431Sdim  if (!LoadedObject)
177221345Sdim    report_fatal_error(Dyld.getErrorString());
178245431Sdim
179245431Sdim  // FIXME: Make this optional, maybe even move it to a JIT event listener
180245431Sdim  LoadedObject->registerWithDebugger();
181245431Sdim
182245431Sdim  NotifyObjectEmitted(*LoadedObject);
183245431Sdim
184263509Sdim  OwnedModules.markModuleAsLoaded(M);
185218885Sdim}
186218885Sdim
187263509Sdimvoid MCJIT::finalizeLoadedModules() {
188263509Sdim  MutexGuard locked(lock);
189263509Sdim
190263509Sdim  // Resolve any outstanding relocations.
191263509Sdim  Dyld.resolveRelocations();
192263509Sdim
193263509Sdim  OwnedModules.markAllLoadedModulesAsFinalized();
194263509Sdim
195263509Sdim  // Register EH frame data for any module we own which has been loaded
196263509Sdim  Dyld.registerEHFrames();
197263509Sdim
198263509Sdim  // Set page permissions.
199263509Sdim  MemMgr.finalizeMemory();
200263509Sdim}
201263509Sdim
202263509Sdim// FIXME: Rename this.
203245431Sdimvoid MCJIT::finalizeObject() {
204263509Sdim  MutexGuard locked(lock);
205263509Sdim
206263509Sdim  for (ModulePtrSet::iterator I = OwnedModules.begin_added(),
207263509Sdim                              E = OwnedModules.end_added();
208263509Sdim       I != E; ++I) {
209263509Sdim    Module *M = *I;
210263509Sdim    generateCodeForModule(M);
211245431Sdim  }
212245431Sdim
213263509Sdim  finalizeLoadedModules();
214263509Sdim}
215252723Sdim
216263509Sdimvoid MCJIT::finalizeModule(Module *M) {
217263509Sdim  MutexGuard locked(lock);
218263509Sdim
219263509Sdim  // This must be a module which has already been added to this MCJIT instance.
220263509Sdim  assert(OwnedModules.ownsModule(M) && "MCJIT::finalizeModule: Unknown module.");
221263509Sdim
222263509Sdim  // If the module hasn't been compiled, just do that.
223263509Sdim  if (!OwnedModules.hasModuleBeenLoaded(M))
224263509Sdim    generateCodeForModule(M);
225263509Sdim
226263509Sdim  finalizeLoadedModules();
227218885Sdim}
228218885Sdim
229218885Sdimvoid *MCJIT::getPointerToBasicBlock(BasicBlock *BB) {
230218885Sdim  report_fatal_error("not yet implemented");
231218885Sdim}
232218885Sdim
233263509Sdimuint64_t MCJIT::getExistingSymbolAddress(const std::string &Name) {
234263509Sdim  // Check with the RuntimeDyld to see if we already have this symbol.
235263509Sdim  if (Name[0] == '\1')
236263509Sdim    return Dyld.getSymbolLoadAddress(Name.substr(1));
237263509Sdim  return Dyld.getSymbolLoadAddress((TM->getMCAsmInfo()->getGlobalPrefix()
238263509Sdim                                       + Name));
239263509Sdim}
240263509Sdim
241263509SdimModule *MCJIT::findModuleForSymbol(const std::string &Name,
242263509Sdim                                   bool CheckFunctionsOnly) {
243263509Sdim  MutexGuard locked(lock);
244263509Sdim
245263509Sdim  // If it hasn't already been generated, see if it's in one of our modules.
246263509Sdim  for (ModulePtrSet::iterator I = OwnedModules.begin_added(),
247263509Sdim                              E = OwnedModules.end_added();
248263509Sdim       I != E; ++I) {
249263509Sdim    Module *M = *I;
250263509Sdim    Function *F = M->getFunction(Name);
251263509Sdim    if (F && !F->isDeclaration())
252263509Sdim      return M;
253263509Sdim    if (!CheckFunctionsOnly) {
254263509Sdim      GlobalVariable *G = M->getGlobalVariable(Name);
255263509Sdim      if (G && !G->isDeclaration())
256263509Sdim        return M;
257263509Sdim      // FIXME: Do we need to worry about global aliases?
258263509Sdim    }
259263509Sdim  }
260263509Sdim  // We didn't find the symbol in any of our modules.
261263509Sdim  return NULL;
262263509Sdim}
263263509Sdim
264263509Sdimuint64_t MCJIT::getSymbolAddress(const std::string &Name,
265263509Sdim                                 bool CheckFunctionsOnly)
266263509Sdim{
267263509Sdim  MutexGuard locked(lock);
268263509Sdim
269263509Sdim  // First, check to see if we already have this symbol.
270263509Sdim  uint64_t Addr = getExistingSymbolAddress(Name);
271263509Sdim  if (Addr)
272263509Sdim    return Addr;
273263509Sdim
274263509Sdim  // If it hasn't already been generated, see if it's in one of our modules.
275263509Sdim  Module *M = findModuleForSymbol(Name, CheckFunctionsOnly);
276263509Sdim  if (!M)
277263509Sdim    return 0;
278263509Sdim
279263509Sdim  generateCodeForModule(M);
280263509Sdim
281263509Sdim  // Check the RuntimeDyld table again, it should be there now.
282263509Sdim  return getExistingSymbolAddress(Name);
283263509Sdim}
284263509Sdim
285263509Sdimuint64_t MCJIT::getGlobalValueAddress(const std::string &Name) {
286263509Sdim  MutexGuard locked(lock);
287263509Sdim  uint64_t Result = getSymbolAddress(Name, false);
288263509Sdim  if (Result != 0)
289263509Sdim    finalizeLoadedModules();
290263509Sdim  return Result;
291263509Sdim}
292263509Sdim
293263509Sdimuint64_t MCJIT::getFunctionAddress(const std::string &Name) {
294263509Sdim  MutexGuard locked(lock);
295263509Sdim  uint64_t Result = getSymbolAddress(Name, true);
296263509Sdim  if (Result != 0)
297263509Sdim    finalizeLoadedModules();
298263509Sdim  return Result;
299263509Sdim}
300263509Sdim
301263509Sdim// Deprecated.  Use getFunctionAddress instead.
302218885Sdimvoid *MCJIT::getPointerToFunction(Function *F) {
303263509Sdim  MutexGuard locked(lock);
304245431Sdim
305221345Sdim  if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
306221345Sdim    bool AbortOnFailure = !F->hasExternalWeakLinkage();
307221345Sdim    void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure);
308221345Sdim    addGlobalMapping(F, Addr);
309221345Sdim    return Addr;
310221345Sdim  }
311221345Sdim
312263509Sdim  Module *M = F->getParent();
313263509Sdim  bool HasBeenAddedButNotLoaded = OwnedModules.hasModuleBeenAddedButNotLoaded(M);
314263509Sdim
315263509Sdim  // Make sure the relevant module has been compiled and loaded.
316263509Sdim  if (HasBeenAddedButNotLoaded)
317263509Sdim    generateCodeForModule(M);
318263509Sdim  else if (!OwnedModules.hasModuleBeenLoaded(M))
319263509Sdim    // If this function doesn't belong to one of our modules, we're done.
320263509Sdim    return NULL;
321263509Sdim
322245431Sdim  // FIXME: Should the Dyld be retaining module information? Probably not.
323223017Sdim  // FIXME: Should we be using the mangler for this? Probably.
324245431Sdim  //
325245431Sdim  // This is the accessor for the target address, so make sure to check the
326245431Sdim  // load address of the symbol, not the local address.
327223017Sdim  StringRef BaseName = F->getName();
328223017Sdim  if (BaseName[0] == '\1')
329245431Sdim    return (void*)Dyld.getSymbolLoadAddress(BaseName.substr(1));
330245431Sdim  return (void*)Dyld.getSymbolLoadAddress((TM->getMCAsmInfo()->getGlobalPrefix()
331223017Sdim                                       + BaseName).str());
332218885Sdim}
333218885Sdim
334218885Sdimvoid *MCJIT::recompileAndRelinkFunction(Function *F) {
335218885Sdim  report_fatal_error("not yet implemented");
336218885Sdim}
337218885Sdim
338218885Sdimvoid MCJIT::freeMachineCodeForFunction(Function *F) {
339218885Sdim  report_fatal_error("not yet implemented");
340218885Sdim}
341218885Sdim
342263509Sdimvoid MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
343263509Sdim    bool isDtors, ModulePtrSet::iterator I, ModulePtrSet::iterator E) {
344263509Sdim  for (; I != E; ++I) {
345263509Sdim    ExecutionEngine::runStaticConstructorsDestructors(*I, isDtors);
346263509Sdim  }
347263509Sdim}
348263509Sdim
349263509Sdimvoid MCJIT::runStaticConstructorsDestructors(bool isDtors) {
350263509Sdim  // Execute global ctors/dtors for each module in the program.
351263509Sdim  runStaticConstructorsDestructorsInModulePtrSet(
352263509Sdim      isDtors, OwnedModules.begin_added(), OwnedModules.end_added());
353263509Sdim  runStaticConstructorsDestructorsInModulePtrSet(
354263509Sdim      isDtors, OwnedModules.begin_loaded(), OwnedModules.end_loaded());
355263509Sdim  runStaticConstructorsDestructorsInModulePtrSet(
356263509Sdim      isDtors, OwnedModules.begin_finalized(), OwnedModules.end_finalized());
357263509Sdim}
358263509Sdim
359263509SdimFunction *MCJIT::FindFunctionNamedInModulePtrSet(const char *FnName,
360263509Sdim                                                 ModulePtrSet::iterator I,
361263509Sdim                                                 ModulePtrSet::iterator E) {
362263509Sdim  for (; I != E; ++I) {
363263509Sdim    if (Function *F = (*I)->getFunction(FnName))
364263509Sdim      return F;
365263509Sdim  }
366263509Sdim  return 0;
367263509Sdim}
368263509Sdim
369263509SdimFunction *MCJIT::FindFunctionNamed(const char *FnName) {
370263509Sdim  Function *F = FindFunctionNamedInModulePtrSet(
371263509Sdim      FnName, OwnedModules.begin_added(), OwnedModules.end_added());
372263509Sdim  if (!F)
373263509Sdim    F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_loaded(),
374263509Sdim                                        OwnedModules.end_loaded());
375263509Sdim  if (!F)
376263509Sdim    F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_finalized(),
377263509Sdim                                        OwnedModules.end_finalized());
378263509Sdim  return F;
379263509Sdim}
380263509Sdim
381218885SdimGenericValue MCJIT::runFunction(Function *F,
382218885Sdim                                const std::vector<GenericValue> &ArgValues) {
383221345Sdim  assert(F && "Function *F was null at entry to run()");
384221345Sdim
385221345Sdim  void *FPtr = getPointerToFunction(F);
386221345Sdim  assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
387226890Sdim  FunctionType *FTy = F->getFunctionType();
388226890Sdim  Type *RetTy = FTy->getReturnType();
389221345Sdim
390221345Sdim  assert((FTy->getNumParams() == ArgValues.size() ||
391221345Sdim          (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&
392221345Sdim         "Wrong number of arguments passed into function!");
393221345Sdim  assert(FTy->getNumParams() == ArgValues.size() &&
394221345Sdim         "This doesn't support passing arguments through varargs (yet)!");
395221345Sdim
396221345Sdim  // Handle some common cases first.  These cases correspond to common `main'
397221345Sdim  // prototypes.
398221345Sdim  if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
399221345Sdim    switch (ArgValues.size()) {
400221345Sdim    case 3:
401221345Sdim      if (FTy->getParamType(0)->isIntegerTy(32) &&
402221345Sdim          FTy->getParamType(1)->isPointerTy() &&
403221345Sdim          FTy->getParamType(2)->isPointerTy()) {
404221345Sdim        int (*PF)(int, char **, const char **) =
405221345Sdim          (int(*)(int, char **, const char **))(intptr_t)FPtr;
406221345Sdim
407221345Sdim        // Call the function.
408221345Sdim        GenericValue rv;
409221345Sdim        rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
410221345Sdim                                 (char **)GVTOP(ArgValues[1]),
411221345Sdim                                 (const char **)GVTOP(ArgValues[2])));
412221345Sdim        return rv;
413221345Sdim      }
414221345Sdim      break;
415221345Sdim    case 2:
416221345Sdim      if (FTy->getParamType(0)->isIntegerTy(32) &&
417221345Sdim          FTy->getParamType(1)->isPointerTy()) {
418221345Sdim        int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr;
419221345Sdim
420221345Sdim        // Call the function.
421221345Sdim        GenericValue rv;
422221345Sdim        rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
423221345Sdim                                 (char **)GVTOP(ArgValues[1])));
424221345Sdim        return rv;
425221345Sdim      }
426221345Sdim      break;
427221345Sdim    case 1:
428221345Sdim      if (FTy->getNumParams() == 1 &&
429221345Sdim          FTy->getParamType(0)->isIntegerTy(32)) {
430221345Sdim        GenericValue rv;
431221345Sdim        int (*PF)(int) = (int(*)(int))(intptr_t)FPtr;
432221345Sdim        rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
433221345Sdim        return rv;
434221345Sdim      }
435221345Sdim      break;
436221345Sdim    }
437221345Sdim  }
438221345Sdim
439221345Sdim  // Handle cases where no arguments are passed first.
440221345Sdim  if (ArgValues.empty()) {
441221345Sdim    GenericValue rv;
442221345Sdim    switch (RetTy->getTypeID()) {
443221345Sdim    default: llvm_unreachable("Unknown return type for function call!");
444221345Sdim    case Type::IntegerTyID: {
445221345Sdim      unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
446221345Sdim      if (BitWidth == 1)
447221345Sdim        rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)());
448221345Sdim      else if (BitWidth <= 8)
449221345Sdim        rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)());
450221345Sdim      else if (BitWidth <= 16)
451221345Sdim        rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)());
452221345Sdim      else if (BitWidth <= 32)
453221345Sdim        rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)());
454221345Sdim      else if (BitWidth <= 64)
455221345Sdim        rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)());
456221345Sdim      else
457221345Sdim        llvm_unreachable("Integer types > 64 bits not supported");
458221345Sdim      return rv;
459221345Sdim    }
460221345Sdim    case Type::VoidTyID:
461221345Sdim      rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)());
462221345Sdim      return rv;
463221345Sdim    case Type::FloatTyID:
464221345Sdim      rv.FloatVal = ((float(*)())(intptr_t)FPtr)();
465221345Sdim      return rv;
466221345Sdim    case Type::DoubleTyID:
467221345Sdim      rv.DoubleVal = ((double(*)())(intptr_t)FPtr)();
468221345Sdim      return rv;
469221345Sdim    case Type::X86_FP80TyID:
470221345Sdim    case Type::FP128TyID:
471221345Sdim    case Type::PPC_FP128TyID:
472221345Sdim      llvm_unreachable("long double not supported yet");
473221345Sdim    case Type::PointerTyID:
474221345Sdim      return PTOGV(((void*(*)())(intptr_t)FPtr)());
475221345Sdim    }
476221345Sdim  }
477221345Sdim
478235633Sdim  llvm_unreachable("Full-featured argument passing not supported yet!");
479218885Sdim}
480235633Sdim
481235633Sdimvoid *MCJIT::getPointerToNamedFunction(const std::string &Name,
482245431Sdim                                       bool AbortOnFailure) {
483263509Sdim  if (!isSymbolSearchingDisabled()) {
484263509Sdim    void *ptr = MemMgr.getPointerToNamedFunction(Name, false);
485235633Sdim    if (ptr)
486235633Sdim      return ptr;
487235633Sdim  }
488235633Sdim
489235633Sdim  /// If a LazyFunctionCreator is installed, use it to get/create the function.
490235633Sdim  if (LazyFunctionCreator)
491235633Sdim    if (void *RP = LazyFunctionCreator(Name))
492235633Sdim      return RP;
493235633Sdim
494235633Sdim  if (AbortOnFailure) {
495235633Sdim    report_fatal_error("Program used external function '"+Name+
496245431Sdim                       "' which could not be resolved!");
497235633Sdim  }
498235633Sdim  return 0;
499235633Sdim}
500245431Sdim
501245431Sdimvoid MCJIT::RegisterJITEventListener(JITEventListener *L) {
502245431Sdim  if (L == NULL)
503245431Sdim    return;
504245431Sdim  MutexGuard locked(lock);
505245431Sdim  EventListeners.push_back(L);
506245431Sdim}
507245431Sdimvoid MCJIT::UnregisterJITEventListener(JITEventListener *L) {
508245431Sdim  if (L == NULL)
509245431Sdim    return;
510245431Sdim  MutexGuard locked(lock);
511245431Sdim  SmallVector<JITEventListener*, 2>::reverse_iterator I=
512245431Sdim      std::find(EventListeners.rbegin(), EventListeners.rend(), L);
513245431Sdim  if (I != EventListeners.rend()) {
514245431Sdim    std::swap(*I, EventListeners.back());
515245431Sdim    EventListeners.pop_back();
516245431Sdim  }
517245431Sdim}
518245431Sdimvoid MCJIT::NotifyObjectEmitted(const ObjectImage& Obj) {
519245431Sdim  MutexGuard locked(lock);
520263509Sdim  MemMgr.notifyObjectLoaded(this, &Obj);
521245431Sdim  for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) {
522245431Sdim    EventListeners[I]->NotifyObjectEmitted(Obj);
523245431Sdim  }
524245431Sdim}
525245431Sdimvoid MCJIT::NotifyFreeingObject(const ObjectImage& Obj) {
526245431Sdim  MutexGuard locked(lock);
527245431Sdim  for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) {
528245431Sdim    EventListeners[I]->NotifyFreeingObject(Obj);
529245431Sdim  }
530245431Sdim}
531263509Sdim
532263509Sdimuint64_t LinkingMemoryManager::getSymbolAddress(const std::string &Name) {
533263509Sdim  uint64_t Result = ParentEngine->getSymbolAddress(Name, false);
534263509Sdim  // If the symbols wasn't found and it begins with an underscore, try again
535263509Sdim  // without the underscore.
536263509Sdim  if (!Result && Name[0] == '_')
537263509Sdim    Result = ParentEngine->getSymbolAddress(Name.substr(1), false);
538263509Sdim  if (Result)
539263509Sdim    return Result;
540263509Sdim  return ClientMM->getSymbolAddress(Name);
541263509Sdim}
542