Ver Fonte

Trying to make LLI works with C++ (work in progress)

HOLZSCHUCH Nicolas há 6 anos atrás
pai
commit
655e72e9e1

+ 4 - 0
frameworks/frameworks.xcodeproj/project.pbxproj

@@ -128,6 +128,7 @@
 		22C505C9209A3B8700FDDFA9 /* liblli.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22C505C8209A3B8700FDDFA9 /* liblli.a */; };
 		22C505CD209A3CB500FDDFA9 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 22C505CC209A3CB500FDDFA9 /* libc++.tbd */; };
 		22C505D1209A3CF700FDDFA9 /* ios_system.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22C505D0209A3CF700FDDFA9 /* ios_system.framework */; };
+		22F9512F20AF0677006268D5 /* libobjc.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 22C1D2E720A841E60093127F /* libobjc.tbd */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
@@ -252,6 +253,7 @@
 		223794C8209B566E00B15016 /* libxml2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.tbd; path = usr/lib/libxml2.tbd; sourceTree = SDKROOT; };
 		223794CA209B568A00B15016 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
 		223794CC209B56AF00B15016 /* libcurses.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurses.tbd; path = usr/lib/libcurses.tbd; sourceTree = SDKROOT; };
+		22C1D2E720A841E60093127F /* libobjc.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libobjc.tbd; path = usr/lib/libobjc.tbd; sourceTree = SDKROOT; };
 		22C505BC209A3B5800FDDFA9 /* lli.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = lli.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		22C505C8209A3B8700FDDFA9 /* liblli.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblli.a; path = ../build_ios/lib/liblli.a; sourceTree = "<group>"; };
 		22C505CA209A3BF400FDDFA9 /* libLLVM.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libLLVM.dylib; path = ../build_ios/lib/libLLVM.dylib; sourceTree = "<group>"; };
@@ -344,6 +346,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				22F9512F20AF0677006268D5 /* libobjc.tbd in Frameworks */,
 				223794CD209B56AF00B15016 /* libcurses.tbd in Frameworks */,
 				223794CB209B568A00B15016 /* libz.tbd in Frameworks */,
 				223794C9209B566E00B15016 /* libxml2.tbd in Frameworks */,
@@ -512,6 +515,7 @@
 		22C505C7209A3B8700FDDFA9 /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				22C1D2E720A841E60093127F /* libobjc.tbd */,
 				223794CC209B56AF00B15016 /* libcurses.tbd */,
 				223794CA209B568A00B15016 /* libz.tbd */,
 				223794C8209B566E00B15016 /* libxml2.tbd */,

+ 1 - 1
lib/CodeGen/IntrinsicLowering.cpp

@@ -357,7 +357,7 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
   default:
     report_fatal_error("Code generator does not support intrinsic function '"+
                       Callee->getName()+"'!");
-  	
+
   case Intrinsic::expect: {
     // Just replace __builtin_expect(exp, c) with EXP.
     Value *V = CI->getArgOperand(0);

+ 40 - 1
lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp

@@ -59,6 +59,9 @@
 #ifdef __APPLE__
 #include <TargetConditionals.h>
 #if (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)
+#include <CoreFoundation/CoreFoundation.h>
+#include <objc/objc.h>
+#include <objc/message.h>
 #include "ios_error.h"
 #include <fcntl.h>
 #endif
@@ -150,6 +153,10 @@ static ffi_type *ffiTypeFor(Type *Ty) {
     default: break;
   }
   // TODO: Support other types such as StructTyID, ArrayTyID, OpaqueTyID, etc.
+  // So, for Swift, it's a StructTyID that breaks things. 
+#if (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)
+  fprintf(thread_stderr, "Type error: type= %d \n", Ty->getTypeID());
+#endif
   report_fatal_error("Type could not be mapped for use with libffi.");
   return NULL;
 }
@@ -198,6 +205,9 @@ static void *ffiValueFor(Type *Ty, const GenericValue &AV,
     default: break;
   }
   // TODO: Support other types such as StructTyID, ArrayTyID, OpaqueTyID, etc.
+#if (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)
+  fprintf(thread_stderr, "Type value error: type= %d \n", Ty->getTypeID());
+#endif
   report_fatal_error("Type value could not be mapped for use with libffi.");
   return NULL;
 }
@@ -474,7 +484,7 @@ static GenericValue lle_X_scanf(FunctionType *FT, ArrayRef<GenericValue> args) {
                   Args[5], Args[6], Args[7], Args[8], Args[9]));
 #else
   GV.IntVal = APInt(32, scanf( Args[0], Args[1], Args[2], Args[3], Args[4],
-                  Args[5], Args[6], Args[7], Args[8], Args[9]));
+                    Args[5], Args[6], Args[7], Args[8], Args[9]));
 #endif
   return GV;
 }
@@ -593,6 +603,32 @@ static GenericValue lle_X_errx(FunctionType *FT, ArrayRef<GenericValue> Args) {
 	return GenericValue();
 }
 
+// Objective-C:
+static GenericValue lle_X_objc_msgSend(FunctionType *FT,
+                                 ArrayRef<GenericValue> args) {
+	// Note: that method fails at runtime, with: 
+	// selector () for message 'stringByAppendingString:' does not match selector known to Objective C runtime ()-- abort
+	// Needs linking with -f Foundation -f CoreFoundation. HOW?
+
+  id self = (objc_object *)GVTOP(args[0]); 
+  SEL op = (SEL)GVTOP(args[1]);
+    
+  GenericValue GV;
+  if (args.size() <= 2) 
+	  GV.PointerVal = *(void **) objc_msgSend(self, op); 
+  else {
+	  objc_object *Args[10];
+	  for (unsigned i = 2; i < args.size(); ++i)
+		  Args[i - 2] = (objc_object *)GVTOP(args[i]);
+
+	  GenericValue GV;
+	  // Add -lobjc to bootstrap.sh before removal
+	  GV.PointerVal = *(void **) (id)objc_msgSend(self, op, Args[0], Args[1], Args[2], Args[3], Args[4],
+			  Args[5], Args[6], Args[7], Args[8], Args[9]);
+  }
+  return GV;
+}
+// 
 
 #endif //  (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)
 
@@ -601,6 +637,7 @@ void Interpreter::initializeExternalFunctions() {
   (*FuncNames)["lle_X_atexit"]       = lle_X_atexit;
   (*FuncNames)["lle_X_exit"]         = lle_X_exit;
   (*FuncNames)["lle_X_abort"]        = lle_X_abort;
+
   (*FuncNames)["lle_X_printf"]       = lle_X_printf;
   (*FuncNames)["lle_X_sprintf"]      = lle_X_sprintf;
   (*FuncNames)["lle_X_sscanf"]       = lle_X_sscanf;
@@ -616,5 +653,7 @@ void Interpreter::initializeExternalFunctions() {
   (*FuncNames)["lle_X_errx"]     = lle_X_errx;
   (*FuncNames)["lle_X_warn"]     = lle_X_warn;
   (*FuncNames)["lle_X_warnx"]     = lle_X_warnx;
+  // objective-C
+  (*FuncNames)["lle_X_objc_msgSend"]     = lle_X_objc_msgSend;
 #endif
 }

+ 15 - 0
lib/ExecutionEngine/Interpreter/Interpreter.cpp

@@ -18,6 +18,15 @@
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Module.h"
 #include <cstring>
+
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#if (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)
+#include "ios_error.h"
+#include "llvm/Support/DynamicLibrary.h"
+#endif
+#endif
+
 using namespace llvm;
 
 namespace {
@@ -59,6 +68,12 @@ Interpreter::Interpreter(std::unique_ptr<Module> M)
   // Initialize the "backend"
   initializeExecutionEngine();
   initializeExternalFunctions();
+#if (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)
+  // Works without it if you don't need the ios_system modifications
+  // (writing to thread_stdout, calling system()...)
+  llvm::sys::DynamicLibrary::LoadLibraryPermanently("libc++.1.dylib");
+  llvm::sys::DynamicLibrary::LoadLibraryPermanently("libc++abi.1.dylib");
+#endif
   emitGlobals();
 
   IL = new IntrinsicLowering(getDataLayout());

+ 4 - 1
lib/Support/CommandLine.cpp

@@ -2221,7 +2221,9 @@ void cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories,
   }
 }
 
-void cl::ResetCommandLineParser() { GlobalParser->reset(); }
+void cl::ResetCommandLineParser() { 
+	GlobalParser->reset(); 
+}
 void cl::ResetAllOptionOccurrences() {
   GlobalParser->ResetAllOptionOccurrences();
 }
@@ -2231,3 +2233,4 @@ void LLVMParseCommandLineOptions(int argc, const char *const *argv,
   llvm::cl::ParseCommandLineOptions(argc, argv, StringRef(Overview),
                                     &llvm::nulls());
 }
+

+ 5 - 5
lib/Support/DynamicLibrary.cpp

@@ -82,7 +82,7 @@ public:
   }
 
   void *LibLookup(const char *Symbol, DynamicLibrary::SearchOrdering Order) {
-    if (Order & SO_LoadOrder) {
+    if (1 /* Order & SO_LoadOrder */) {
       for (void *Handle : Handles) {
         if (void *Ptr = DLSym(Handle, Symbol))
           return Ptr;
@@ -100,7 +100,7 @@ public:
     assert(!((Order & SO_LoadedFirst) && (Order & SO_LoadedLast)) &&
            "Invalid Ordering");
 
-    if (!Process || (Order & SO_LoadedFirst)) {
+    if (1 /* !Process || (Order & SO_LoadedFirst)*/) {
       if (void *Ptr = LibLookup(Symbol, Order))
         return Ptr;
     }
@@ -110,7 +110,7 @@ public:
         return Ptr;
 
       // Search any libs that might have been skipped because of RTLD_LOCAL.
-      if (Order & SO_LoadedLast) {
+      if (Order  & SO_LoadedLast) {
         if (void *Ptr = LibLookup(Symbol, Order))
           return Ptr;
       }
@@ -142,7 +142,6 @@ char DynamicLibrary::Invalid;
 DynamicLibrary::SearchOrdering DynamicLibrary::SearchOrder =
     DynamicLibrary::SO_Linker;
 
-
 namespace llvm {
 void *SearchForAddressOfSpecialSymbol(const char *SymbolName) {
   return DoSearch(SymbolName); // DynamicLibrary.inc
@@ -215,10 +214,11 @@ void *DynamicLibrary::SearchForAddressOfSymbol(const char *SymbolName) {
 
     // Now search the libraries.
     if (OpenedHandles.isConstructed()) {
-      if (void *Ptr = OpenedHandles->Lookup(SymbolName, SearchOrder))
+      if (void *Ptr = OpenedHandles->Lookup(SymbolName, SearchOrder ))
         return Ptr;
     }
   }
+
   return llvm::SearchForAddressOfSpecialSymbol(SymbolName);
 }
 

+ 11 - 0
lib/Support/ManagedStatic.cpp

@@ -17,6 +17,17 @@
 #include "llvm/Support/MutexGuard.h"
 #include "llvm/Support/Threading.h"
 #include <cassert>
+
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#if (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)
+#include <llvm-c/Support.h>
+#include "ios_error.h"
+#undef write
+#undef exit
+#endif
+#endif
+
 using namespace llvm;
 
 static const ManagedStaticBase *StaticList = nullptr;

+ 5 - 6
lib/Support/Unix/DynamicLibrary.inc

@@ -10,9 +10,6 @@
 // This file provides the UNIX specific implementation of DynamicLibrary.
 //
 //===----------------------------------------------------------------------===//
-// #if (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)
-// #include "llvm/Support/raw_ostream.h"
-// #endif
 #if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
 #include <dlfcn.h>
 
@@ -28,8 +25,10 @@ DynamicLibrary::HandleSet::~HandleSet() {
 }
 
 void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
+  fprintf(stderr, "DLOpen %s \n", File); fflush(stderr);
   void *Handle = ::dlopen(File, RTLD_LAZY|RTLD_GLOBAL);
   if (!Handle) {
+	  fprintf(stderr, "Could not load library %s: %s \n", File, ::dlerror()); fflush(stderr);
     if (Err) *Err = ::dlerror();
     return &DynamicLibrary::Invalid;
   }
@@ -53,18 +52,18 @@ void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
 	const char* symbolName = Symbol;
 	// Works, but why? deMangleName?
 	void* returnPtr = ::dlsym(Handle, symbolName);
-	// outs() << "Trying " << symbolName << ", got " << returnPtr << "\n"; outs().flush(); fflush(thread_stdout);  
+	fprintf(stderr, "Trying %s, got %x \n", symbolName, returnPtr);  fflush(stderr);  
 	if (returnPtr) return returnPtr;
 	if (symbolName[0] == '\x01') {
 		symbolName += 1;
 		returnPtr = ::dlsym(Handle, symbolName);
-		// outs() << "Trying " << symbolName << ", got " << returnPtr << "\n"; outs().flush(); fflush(thread_stdout);  
+		fprintf(stderr, "Trying %s, got %x \n", symbolName, returnPtr);  fflush(stderr);  
 	}
 	if (returnPtr) return returnPtr;
 	if (symbolName[0] == '_') {
 		symbolName += 1;
 		returnPtr = ::dlsym(Handle, symbolName);
-		// outs() << "Trying " << symbolName << ", got " << returnPtr << "\n"; outs().flush(); fflush(thread_stdout);  
+		fprintf(stderr, "Trying %s, got %x \n", symbolName, returnPtr);  fflush(stderr);  
 	}
 	return returnPtr;
 #else

+ 1 - 0
projects/libcxx

@@ -0,0 +1 @@
+Subproject commit 8fc472d96acf25b63d3faf3bd5101e654de04b42

+ 1 - 0
projects/libcxxabi

@@ -0,0 +1 @@
+Subproject commit 05a73941f3fb177c4a891d4ff2a4ed5785e3b80c

+ 10 - 0
tools/lli/lli.cpp

@@ -73,6 +73,12 @@
 #define exit(a) { llvm_shutdown(); ios_exit(a); }
 extern "C" {
 extern const char* llvm_ios_progname;
+// TODO: add these to the list of symbols, plus _dso_handle, plus __cxa_atexit
+// Q = interpreter only?
+// dso_handle *could* be the pointer for libstdc++?
+// raw_fd_ostream standard_out(STDOUT_FILENO, false, false);
+// raw_fd_ostream standard_err(STDERR_FILENO, false, true);
+
 void llvm_ios_exit(int a) { llvm_shutdown(); ios_exit(a); }
 void llvm_ios_abort(int a) { report_fatal_error("LLVM JIT compiled program raised SIGABRT"); }
 int llvm_ios_putchar(char c) { return fputc(c, thread_stdout); }
@@ -595,6 +601,10 @@ int main(int argc, char **argv, char * const *envp) {
 	  sys::DynamicLibrary::AddSymbol("warnx", (void*)&llvm_ios_warnx);
 	  sys::DynamicLibrary::AddSymbol("vwarn", (void*)&llvm_ios_vwarn);
 	  sys::DynamicLibrary::AddSymbol("vwarnx", (void*)&llvm_ios_vwarnx);
+	  // External C++ symbols (todo)
+	  sys::DynamicLibrary::AddSymbol("__dso_handle", NULL);
+	  // sys::DynamicLibrary::AddSymbol("_ZSt4cout", &standard_out);
+	  // sys::DynamicLibrary::AddSymbol("_ZSt4cerr", &standard_err);
 #endif  
 
   std::unique_ptr<ExecutionEngine> EE(builder.create());