[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.

2018-03-14 Thread Frederich Munch via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC327528: Expand clang-interpreter with example of throwing in 
and from the JIT for… (authored by marsupial, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D35103

Files:
  examples/clang-interpreter/CMakeLists.txt
  examples/clang-interpreter/Invoke.cpp
  examples/clang-interpreter/Invoke.h
  examples/clang-interpreter/Manager.cpp
  examples/clang-interpreter/Manager.h
  examples/clang-interpreter/README.txt
  examples/clang-interpreter/Test.cxx
  examples/clang-interpreter/main.cpp

Index: examples/clang-interpreter/Invoke.cpp
===
--- examples/clang-interpreter/Invoke.cpp
+++ examples/clang-interpreter/Invoke.cpp
@@ -0,0 +1,31 @@
+//==-- examples/clang-interpreter/Invoke.cpp - Clang C Interpreter Example -==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "Invoke.h"
+
+#include 
+#include 
+
+namespace interpreter {
+
+int TryIt(llvm::ExecutionEngine *EE, llvm::Function *EntryFn,
+  const std::vector , char *const *EnvP,
+  Invoker Invoke) {
+  int Res = -1;
+  try {
+Res = Invoke(EE, EntryFn, Args, EnvP);
+  } catch (const std::exception ) {
+std::cout << "Caught '" << E.what() << "'\n";
+  } catch (...) {
+std::cout << "Unknown exception\n";
+  }
+  return Res;
+}
+
+}
Index: examples/clang-interpreter/README.txt
===
--- examples/clang-interpreter/README.txt
+++ examples/clang-interpreter/README.txt
@@ -1,4 +1,4 @@
-This is an example of Clang based interpreter, for executing standalone C
+This is an example of Clang based interpreter, for executing standalone C/C++
 programs.
 
 It demonstrates the following features:
@@ -12,6 +12,9 @@
 
  4. Use the LLVM JIT functionality to execute the final module.
 
+ 5. Intercepting a Win64 library call to allow throwing and catching exceptions
+in and from the JIT.
+
 The implementation has many limitations and is not designed to be a full fledged
-C interpreter. It is designed to demonstrate a simple but functional use of the
+interpreter. It is designed to demonstrate a simple but functional use of the
 Clang compiler libraries.
Index: examples/clang-interpreter/Manager.cpp
===
--- examples/clang-interpreter/Manager.cpp
+++ examples/clang-interpreter/Manager.cpp
@@ -0,0 +1,328 @@
+//==-- examples/clang-interpreter/Manager.cpp - Clang C Interpreter Example -=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "Manager.h"
+
+#ifdef CLANG_INTERPRETER_WIN_EXCEPTIONS
+#include "llvm/Support/DynamicLibrary.h"
+
+#define WIN32_LEAN_AND_MEAN
+#define NOGDI
+#define NOMINMAX
+#include 
+#endif
+
+namespace interpreter {
+
+using namespace llvm;
+
+void SingleSectionMemoryManager::Block::Reset(uint8_t *Ptr, uintptr_t Size) {
+  assert(Ptr != nullptr && "Bad allocation");
+  Addr = Ptr;
+  End = Ptr ? Ptr + Size : nullptr;
+}
+
+uint8_t *SingleSectionMemoryManager::Block::Next(uintptr_t Size,
+ unsigned Alignment) {
+  uintptr_t Out = (uintptr_t)Addr;
+
+  // Align the out pointer properly
+  if (!Alignment)
+Alignment = 16;
+  Out = (Out + Alignment - 1) & ~(uintptr_t)(Alignment - 1);
+
+  // RuntimeDyld should have called reserveAllocationSpace with an amount that
+  // will fit all required alignemnts...but assert on this to make sure.
+  assert((Out + Size) <= (uintptr_t)End && "Out of bounds");
+
+  // Set the next Addr to deliver at the end of this one.
+  Addr = (uint8_t *)(Out + Size);
+  return (uint8_t *)Out;
+}
+
+uint8_t *SingleSectionMemoryManager::allocateCodeSection(uintptr_t Size,
+ unsigned Align,
+ unsigned ID,
+ StringRef Name) {
+  return Code.Next(Size, Align);
+}
+
+uint8_t *SingleSectionMemoryManager::allocateDataSection(
+uintptr_t Size, unsigned Align, unsigned ID, StringRef Name, bool RO) {
+  return RO ? ROData.Next(Size, Align) : RWData.Next(Size, Align);
+}
+
+void SingleSectionMemoryManager::reserveAllocationSpace(
+uintptr_t CodeSize, uint32_t CodeAlign, uintptr_t ROSize, uint32_t ROAlign,
+uintptr_t RWSize, uint32_t RWAlign) {
+  // FIXME: Ideally this should be one contiguous block, with Code, ROData,
+  // and RWData pointing 

[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.

2018-03-08 Thread Martell Malone via Phabricator via cfe-commits
martell added a comment.
Herald added a subscriber: mgrang.

ping @marsupial


https://reviews.llvm.org/D35103



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.

2017-07-28 Thread Frederich Munch via Phabricator via cfe-commits
marsupial marked 3 inline comments as done.
marsupial added a comment.

Done, thanks. Would it be possible to look at https://reviews.llvm.org/D30709 
as this depends on that. (ELF does not like Windows exceptions).


https://reviews.llvm.org/D35103



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.

2017-07-28 Thread Frederich Munch via Phabricator via cfe-commits
marsupial updated this revision to Diff 108676.
marsupial added a comment.

Use include guards, not pragma once and remove commented CMake debug lines.


https://reviews.llvm.org/D35103

Files:
  examples/clang-interpreter/CMakeLists.txt
  examples/clang-interpreter/Invoke.cpp
  examples/clang-interpreter/Invoke.h
  examples/clang-interpreter/Manager.cpp
  examples/clang-interpreter/Manager.h
  examples/clang-interpreter/README.txt
  examples/clang-interpreter/Test.cxx
  examples/clang-interpreter/main.cpp

Index: examples/clang-interpreter/main.cpp
===
--- examples/clang-interpreter/main.cpp
+++ examples/clang-interpreter/main.cpp
@@ -7,6 +7,9 @@
 //
 //===--===//
 
+#include "Invoke.h"
+#include "Manager.h"
+
 #include "clang/CodeGen/CodeGenAction.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Driver/Compilation.h"
@@ -26,73 +29,61 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/raw_ostream.h"
-#include 
+
 using namespace clang;
 using namespace clang::driver;
 
+namespace interpreter {
+
+static llvm::ExecutionEngine *
+createExecutionEngine(std::unique_ptr M, std::string *ErrorStr) {
+  llvm::EngineBuilder EB(std::move(M));
+  EB.setErrorStr(ErrorStr);
+  EB.setMemoryManager(llvm::make_unique());
+  llvm::ExecutionEngine *EE = EB.create();
+  EE->finalizeObject();
+  return EE;
+}
+
+// Invoked from a try/catch block in invoke.cpp.
+//
+static int Invoke(llvm::ExecutionEngine *EE, llvm::Function *EntryFn,
+  const std::vector , char *const *EnvP) {
+  return EE->runFunctionAsMain(EntryFn, Args, EnvP);
+}
+
 // This function isn't referenced outside its translation unit, but it
 // can't use the "static" keyword because its address is used for
 // GetMainExecutable (since some platforms don't support taking the
 // address of main, and some platforms can't implement GetMainExecutable
 // without being given the address of a function in the main executable).
-std::string GetExecutablePath(const char *Argv0) {
-  // This just needs to be some symbol in the binary; C++ doesn't
-  // allow taking the address of ::main however.
-  void *MainAddr = (void*) (intptr_t) GetExecutablePath;
+std::string GetExecutablePath(const char *Argv0, void *MainAddr) {
   return llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
 }
 
-static llvm::ExecutionEngine *
-createExecutionEngine(std::unique_ptr M, std::string *ErrorStr) {
-  return llvm::EngineBuilder(std::move(M))
-  .setEngineKind(llvm::EngineKind::Either)
-  .setErrorStr(ErrorStr)
-  .create();
-}
-
-static int Execute(std::unique_ptr Mod, char *const *envp) {
-  llvm::InitializeNativeTarget();
-  llvm::InitializeNativeTargetAsmPrinter();
-
-  llvm::Module  = *Mod;
-  std::string Error;
-  std::unique_ptr EE(
-  createExecutionEngine(std::move(Mod), ));
-  if (!EE) {
-llvm::errs() << "unable to make execution engine: " << Error << "\n";
-return 255;
-  }
-
-  llvm::Function *EntryFn = M.getFunction("main");
-  if (!EntryFn) {
-llvm::errs() << "'main' function not found in module.\n";
-return 255;
-  }
-
-  // FIXME: Support passing arguments.
-  std::vector Args;
-  Args.push_back(M.getModuleIdentifier());
-
-  EE->finalizeObject();
-  return EE->runFunctionAsMain(EntryFn, Args, envp);
-}
+} // namespace interpreter
 
 int main(int argc, const char **argv, char * const *envp) {
-  void *MainAddr = (void*) (intptr_t) GetExecutablePath;
-  std::string Path = GetExecutablePath(argv[0]);
+  // This just needs to be some symbol in the binary; C++ doesn't
+  // allow taking the address of ::main however.
+  void *MainAddr = (void*) (intptr_t) interpreter::GetExecutablePath;
+  std::string Path = interpreter::GetExecutablePath(argv[0], MainAddr);
   IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions();
   TextDiagnosticPrinter *DiagClient =
 new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
 
   IntrusiveRefCntPtr DiagID(new DiagnosticIDs());
   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
 
-  // Use ELF on windows for now.
-  std::string TripleStr = llvm::sys::getProcessTriple();
+  const std::string TripleStr = llvm::sys::getProcessTriple();
   llvm::Triple T(TripleStr);
+
+  // Use ELF on Windows-32 and MingW for now.
+#ifndef CLANG_INTERPRETER_COFF_FORMAT
   if (T.isOSBinFormatCOFF())
 T.setObjectFormat(llvm::Triple::ELF);
-
+#endif
+	
   Driver TheDriver(Path, T.str(), Diags);
   TheDriver.setTitle("clang interpreter");
   TheDriver.setCheckInputsExist(false);
@@ -163,12 +154,36 @@
   if (!Clang.ExecuteAction(*Act))
 return 1;
 
+  llvm::InitializeNativeTarget();
+  llvm::InitializeNativeTargetAsmPrinter();
+
   int Res = 255;
-  if (std::unique_ptr Module = Act->takeModule())
-Res = Execute(std::move(Module), envp);
+  if (std::unique_ptr Module = Act->takeModule()) {
+llvm::Function 

[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.

2017-07-25 Thread Lang Hames via Phabricator via cfe-commits
lhames accepted this revision.
lhames added a comment.
This revision is now accepted and ready to land.

Otherwise this looks good to me.




Comment at: examples/clang-interpreter/CMakeLists.txt:73
+set_property(TARGET ${TARGET} PROPERTY COMPILE_FLAGS ${editedFlags})
+#message("COMPILE_FLAGS: '${addedFlags}' '${editedFlags}'")
+

These debugging messages (this and the one below) should probably be stripped.



Comment at: examples/clang-interpreter/Invoke.h:10
+
+#pragma once
+

I believe you should use include guards in LLVM headers. Pragma once should 
work, but I don't think it's standard (and it doesn't seem to be used anywhere 
else in the codebase).



Comment at: examples/clang-interpreter/Manager.h:10
+
+#pragma once
+

Ditto here.


https://reviews.llvm.org/D35103



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.

2017-07-24 Thread Frederich Munch via Phabricator via cfe-commits
marsupial added a comment.

Ping.


https://reviews.llvm.org/D35103



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.

2017-07-13 Thread Frederich Munch via Phabricator via cfe-commits
marsupial marked 3 inline comments as done.
marsupial added a comment.

Done, and changed to 'windows.h', but blocked mingw from even attempting SEH 
for now.


https://reviews.llvm.org/D35103



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.

2017-07-13 Thread Frederich Munch via Phabricator via cfe-commits
marsupial updated this revision to Diff 106548.
marsupial added a comment.

Blocked Win64 SEH for MingW entirely.
Theoretically it should be possible to throw a SEH from within mingw, but but 
I'm thinking clang may be generating exception handlers for the gcc runtime in 
that case.
I'll leave it up to someone with interest in such a mixture to figure that tout.


https://reviews.llvm.org/D35103

Files:
  examples/clang-interpreter/CMakeLists.txt
  examples/clang-interpreter/Invoke.cpp
  examples/clang-interpreter/Invoke.h
  examples/clang-interpreter/Manager.cpp
  examples/clang-interpreter/Manager.h
  examples/clang-interpreter/README.txt
  examples/clang-interpreter/Test.cxx
  examples/clang-interpreter/main.cpp

Index: examples/clang-interpreter/main.cpp
===
--- examples/clang-interpreter/main.cpp
+++ examples/clang-interpreter/main.cpp
@@ -7,6 +7,9 @@
 //
 //===--===//
 
+#include "Invoke.h"
+#include "Manager.h"
+
 #include "clang/CodeGen/CodeGenAction.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Driver/Compilation.h"
@@ -26,73 +29,61 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/raw_ostream.h"
-#include 
+
 using namespace clang;
 using namespace clang::driver;
 
+namespace interpreter {
+
+static llvm::ExecutionEngine *
+createExecutionEngine(std::unique_ptr M, std::string *ErrorStr) {
+  llvm::EngineBuilder EB(std::move(M));
+  EB.setErrorStr(ErrorStr);
+  EB.setMemoryManager(llvm::make_unique());
+  llvm::ExecutionEngine *EE = EB.create();
+  EE->finalizeObject();
+  return EE;
+}
+
+// Invoked from a try/catch block in invoke.cpp.
+//
+static int Invoke(llvm::ExecutionEngine *EE, llvm::Function *EntryFn,
+  const std::vector , char *const *EnvP) {
+  return EE->runFunctionAsMain(EntryFn, Args, EnvP);
+}
+
 // This function isn't referenced outside its translation unit, but it
 // can't use the "static" keyword because its address is used for
 // GetMainExecutable (since some platforms don't support taking the
 // address of main, and some platforms can't implement GetMainExecutable
 // without being given the address of a function in the main executable).
-std::string GetExecutablePath(const char *Argv0) {
-  // This just needs to be some symbol in the binary; C++ doesn't
-  // allow taking the address of ::main however.
-  void *MainAddr = (void*) (intptr_t) GetExecutablePath;
+std::string GetExecutablePath(const char *Argv0, void *MainAddr) {
   return llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
 }
 
-static llvm::ExecutionEngine *
-createExecutionEngine(std::unique_ptr M, std::string *ErrorStr) {
-  return llvm::EngineBuilder(std::move(M))
-  .setEngineKind(llvm::EngineKind::Either)
-  .setErrorStr(ErrorStr)
-  .create();
-}
-
-static int Execute(std::unique_ptr Mod, char *const *envp) {
-  llvm::InitializeNativeTarget();
-  llvm::InitializeNativeTargetAsmPrinter();
-
-  llvm::Module  = *Mod;
-  std::string Error;
-  std::unique_ptr EE(
-  createExecutionEngine(std::move(Mod), ));
-  if (!EE) {
-llvm::errs() << "unable to make execution engine: " << Error << "\n";
-return 255;
-  }
-
-  llvm::Function *EntryFn = M.getFunction("main");
-  if (!EntryFn) {
-llvm::errs() << "'main' function not found in module.\n";
-return 255;
-  }
-
-  // FIXME: Support passing arguments.
-  std::vector Args;
-  Args.push_back(M.getModuleIdentifier());
-
-  EE->finalizeObject();
-  return EE->runFunctionAsMain(EntryFn, Args, envp);
-}
+} // namespace interpreter
 
 int main(int argc, const char **argv, char * const *envp) {
-  void *MainAddr = (void*) (intptr_t) GetExecutablePath;
-  std::string Path = GetExecutablePath(argv[0]);
+  // This just needs to be some symbol in the binary; C++ doesn't
+  // allow taking the address of ::main however.
+  void *MainAddr = (void*) (intptr_t) interpreter::GetExecutablePath;
+  std::string Path = interpreter::GetExecutablePath(argv[0], MainAddr);
   IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions();
   TextDiagnosticPrinter *DiagClient =
 new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
 
   IntrusiveRefCntPtr DiagID(new DiagnosticIDs());
   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
 
-  // Use ELF on windows for now.
-  std::string TripleStr = llvm::sys::getProcessTriple();
+  const std::string TripleStr = llvm::sys::getProcessTriple();
   llvm::Triple T(TripleStr);
+
+  // Use ELF on Windows-32 and MingW for now.
+#ifndef CLANG_INTERPRETER_COFF_FORMAT
   if (T.isOSBinFormatCOFF())
 T.setObjectFormat(llvm::Triple::ELF);
-
+#endif
+	
   Driver TheDriver(Path, T.str(), Diags);
   TheDriver.setTitle("clang interpreter");
   TheDriver.setCheckInputsExist(false);
@@ -163,12 +154,36 @@
   if (!Clang.ExecuteAction(*Act))
 return 1;
 
+  llvm::InitializeNativeTarget();
+  

[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.

2017-07-13 Thread Martell Malone via Phabricator via cfe-commits
martell added inline comments.



Comment at: examples/clang-interpreter/Manager.cpp:18
+#define NOMINMAX
+#include 
+#endif

windows.h with lower case `w` to not break mingw


https://reviews.llvm.org/D35103



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.

2017-07-13 Thread Martell Malone via Phabricator via cfe-commits
martell added a comment.

Just 2 small nits.




Comment at: examples/clang-interpreter/main.cpp:165
+  llvm::errs() << "'main' function not found in module.\n";
+  return 255;
+}

255 -> Res ?



Comment at: examples/clang-interpreter/main.cpp:173
+  llvm::errs() << "unable to make execution engine: " << Error << "\n";
+  return 255;
+}

255 -> Res


https://reviews.llvm.org/D35103



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35103: Expand clang-interpreter with example of throwing in and from the JIT for Windows64.

2017-07-06 Thread Frederich Munch via Phabricator via cfe-commits
marsupial created this revision.
Herald added a subscriber: mgorny.

Getting this to work is not particularly obvious, and having it as an example 
should be helpful.
Portions of this could be placed into LLVM, but as a whole it seems necessary 
to do this a higher level.


https://reviews.llvm.org/D35103

Files:
  examples/clang-interpreter/CMakeLists.txt
  examples/clang-interpreter/Invoke.cpp
  examples/clang-interpreter/Invoke.h
  examples/clang-interpreter/Manager.cpp
  examples/clang-interpreter/Manager.h
  examples/clang-interpreter/README.txt
  examples/clang-interpreter/Test.cxx
  examples/clang-interpreter/main.cpp

Index: examples/clang-interpreter/main.cpp
===
--- examples/clang-interpreter/main.cpp
+++ examples/clang-interpreter/main.cpp
@@ -7,6 +7,9 @@
 //
 //===--===//
 
+#include "Invoke.h"
+#include "Manager.h"
+
 #include "clang/CodeGen/CodeGenAction.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Driver/Compilation.h"
@@ -26,73 +29,61 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/raw_ostream.h"
-#include 
+
 using namespace clang;
 using namespace clang::driver;
 
+namespace interpreter {
+
+static llvm::ExecutionEngine *
+createExecutionEngine(std::unique_ptr M, std::string *ErrorStr) {
+  llvm::EngineBuilder EB(std::move(M));
+  EB.setErrorStr(ErrorStr);
+  EB.setMemoryManager(llvm::make_unique());
+  llvm::ExecutionEngine *EE = EB.create();
+  EE->finalizeObject();
+  return EE;
+}
+
+// Invoked from a try/catch block in invoke.cpp.
+//
+static int Invoke(llvm::ExecutionEngine *EE, llvm::Function *EntryFn,
+  const std::vector , char *const *EnvP) {
+  return EE->runFunctionAsMain(EntryFn, Args, EnvP);
+}
+
 // This function isn't referenced outside its translation unit, but it
 // can't use the "static" keyword because its address is used for
 // GetMainExecutable (since some platforms don't support taking the
 // address of main, and some platforms can't implement GetMainExecutable
 // without being given the address of a function in the main executable).
-std::string GetExecutablePath(const char *Argv0) {
-  // This just needs to be some symbol in the binary; C++ doesn't
-  // allow taking the address of ::main however.
-  void *MainAddr = (void*) (intptr_t) GetExecutablePath;
+std::string GetExecutablePath(const char *Argv0, void *MainAddr) {
   return llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
 }
 
-static llvm::ExecutionEngine *
-createExecutionEngine(std::unique_ptr M, std::string *ErrorStr) {
-  return llvm::EngineBuilder(std::move(M))
-  .setEngineKind(llvm::EngineKind::Either)
-  .setErrorStr(ErrorStr)
-  .create();
-}
-
-static int Execute(std::unique_ptr Mod, char *const *envp) {
-  llvm::InitializeNativeTarget();
-  llvm::InitializeNativeTargetAsmPrinter();
-
-  llvm::Module  = *Mod;
-  std::string Error;
-  std::unique_ptr EE(
-  createExecutionEngine(std::move(Mod), ));
-  if (!EE) {
-llvm::errs() << "unable to make execution engine: " << Error << "\n";
-return 255;
-  }
-
-  llvm::Function *EntryFn = M.getFunction("main");
-  if (!EntryFn) {
-llvm::errs() << "'main' function not found in module.\n";
-return 255;
-  }
-
-  // FIXME: Support passing arguments.
-  std::vector Args;
-  Args.push_back(M.getModuleIdentifier());
-
-  EE->finalizeObject();
-  return EE->runFunctionAsMain(EntryFn, Args, envp);
-}
+} // namespace interpreter
 
 int main(int argc, const char **argv, char * const *envp) {
-  void *MainAddr = (void*) (intptr_t) GetExecutablePath;
-  std::string Path = GetExecutablePath(argv[0]);
+  // This just needs to be some symbol in the binary; C++ doesn't
+  // allow taking the address of ::main however.
+  void *MainAddr = (void*) (intptr_t) interpreter::GetExecutablePath;
+  std::string Path = interpreter::GetExecutablePath(argv[0], MainAddr);
   IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions();
   TextDiagnosticPrinter *DiagClient =
 new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
 
   IntrusiveRefCntPtr DiagID(new DiagnosticIDs());
   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
 
-  // Use ELF on windows for now.
-  std::string TripleStr = llvm::sys::getProcessTriple();
+  const std::string TripleStr = llvm::sys::getProcessTriple();
   llvm::Triple T(TripleStr);
+
+  // Use ELF on Windows-32 for now.
+#if defined(_WIN32) && !defined(_WIN64)
   if (T.isOSBinFormatCOFF())
 T.setObjectFormat(llvm::Triple::ELF);
-
+#endif
+	
   Driver TheDriver(Path, T.str(), Diags);
   TheDriver.setTitle("clang interpreter");
   TheDriver.setCheckInputsExist(false);
@@ -163,12 +154,36 @@
   if (!Clang.ExecuteAction(*Act))
 return 1;
 
+  llvm::InitializeNativeTarget();
+  llvm::InitializeNativeTargetAsmPrinter();
+
   int Res = 255;
-  if (std::unique_ptr Module = Act->takeModule())
-Res =