2012-04-29 17 views
12

Używam języka Clon do kompilowania kodu Obj-C używającego klas Kakao OSX i próbuję uruchomić wynik z Kompilator LLVM JIT. Używam najnowszej najnowszej wersji LLVM/Clang.Wszystkie selektory nierozpoznane podczas wywoływania metod Objective-C za pomocą narzędzia LLVM ExecutionEngine

Nie ma problemów ze skompilowaniem lub połączeniem mojego kodu i mogę bez problemu wykonywać wywołania systemowe C i C++. Ale wszystkie moje inwokacje z Obj-C zawodzą żałośnie, a ja nie potrafię zrozumieć dlaczego! Wydaje się, że funkcja objc_msgSend() jest poprawnie wywoływana, ale środowisko wykonawcze odmawia rozpoznania nawet najprostszych selektorów.

udało mi się odtworzyć problem, używając tylko brzękiem i LLI, a to jest, jak to zrobić:

Tworzenie prostych plików test.mm:

#include <Cocoa/Cocoa.h> 
#include <cstdio> 
#include <iostream> 

extern "C" int main (int, char**) 
{ 
    std::cout << "==== step 1" << std::endl; 

    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 
    [pool release]; 

    std::cout << "==== step 2" << std::endl; 

    return 0; 
} 

..compile nim do bitcode z brzękiem:

clang -emit-llvm test.mm -c -o test.bc 

następnie uruchomić go z LLI:

lli -load=/System/Library/Frameworks/Foundation.framework/Versions/Current/Foundation test.bc 

Wyjście LLI wygląda następująco:

==== step 1 
objc[45353]: Object 0x101a362a0 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug 
2012-04-29 20:07:35.384 lli[45353:707] -[NSAutoreleasePool init]: unrecognized selector sent to instance 0x101a35170 
2012-04-29 20:07:35.386 lli[45353:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSAutoreleasePool init]: unrecognized selector sent to instance 0x101a35170' 
*** First throw call stack: 
(
    0 CoreFoundation      0x00007fff89c76fc6 __exceptionPreprocess + 198 
    1 libobjc.A.dylib      0x00007fff8c9e6d5e objc_exception_throw + 43 
    2 CoreFoundation      0x00007fff89d032ae -[NSObject doesNotRecognizeSelector:] + 190 
    3 CoreFoundation      0x00007fff89c63e73 ___forwarding___ + 371 
    4 CoreFoundation      0x00007fff89c63c88 _CF_forwarding_prep_0 + 232 
    5 ???         0x0000000101929111 0x0 + 4321349905 
    6 lli         0x000000010148f36b _ZN4llvm15ExecutionEngine17runFunctionAsMainEPNS_8FunctionERKSt6vectorISsSaISsEEPKPKc + 1259 
    7 lli         0x0000000101016657 main + 3095 
    8 lli         0x0000000101015a34 start + 52 
    9 ???         0x0000000000000003 0x0 + 3 
) 
terminate called throwing an exception0 lli    0x00000001015c5b02 _ZL15PrintStackTracePv + 34 
1 lli    0x00000001015c5fd9 _ZL13SignalHandleri + 633 
2 libsystem_c.dylib 0x00007fff8f8bccfa _sigtramp + 26 
3 libsystem_c.dylib 0x0000000000000001 _sigtramp + 18446603338107859745 
4 libsystem_c.dylib 0x00007fff8f85ba7a abort + 143 
5 libc++abi.dylib 0x00007fff8518a7bc abort_message + 214 
6 libc++abi.dylib 0x00007fff85187fcf default_terminate() + 28 
7 libobjc.A.dylib 0x00007fff8c9e71b9 _objc_terminate + 94 
8 libc++abi.dylib 0x00007fff85188001 safe_handler_caller(void (*)()) + 11 
9 libc++abi.dylib 0x00007fff8518805c __cxa_bad_typeid + 0 
10 libc++abi.dylib 0x00007fff85189152 __gxx_exception_cleanup(_Unwind_Reason_Code, _Unwind_Exception*) + 0 
11 libobjc.A.dylib 0x00007fff8c9e6e7a _objc_exception_destructor + 0 
12 CoreFoundation 0x00007fff89d032ae -[NSObject doesNotRecognizeSelector:] + 190 
13 CoreFoundation 0x00007fff89c63e73 ___forwarding___ + 371 
14 CoreFoundation 0x00007fff89c63c88 _CF_forwarding_prep_0 + 232 
15 CoreFoundation 0x0000000101929111 _CF_forwarding_prep_0 + 18446603342526043505 
16 lli    0x000000010148f36b llvm::ExecutionEngine::runFunctionAsMain(llvm::Function*, std::vector<std::string, std::allocator<std::string> > const&, char const* const*) + 1259 
17 lli    0x0000000101016657 main + 3095 
18 lli    0x0000000101015a34 start + 52 
19 lli    0x0000000000000003 start + 18446744069397718531 
Stack dump: 
0. Program arguments: Release/bin/lli -load=/System/Library/Frameworks/Foundation.framework/Versions/Current/Foundation /Users/jules/Desktop/test.bc 
Abort trap: 6 

Jak widać w dzienniku, to mówi, że -[NSAutoreleasePool init] jest nierozpoznany selektor. To samo dzieje się w przypadku każdego innego selektora, np. -[NSString init] lub inne rzeczy, które wyraźnie powinny działać.

Każda pomoc lub wskazówki będą mile widziane! Jestem trochę zagubiony, czy to błąd, czy coś, co robię źle, a może po prostu funkcja, która nie została jeszcze zakończona. Nie można znaleźć żadnych odniesień do tego problemu w dokumentacji lub interwebs LLVM.

Próbowałem różnych opcji klangów, takich jak starsza karta ABI Obj-C, ale nie miałem szczęścia. Nie jestem ekspertem ani od LLVM, ani od środowiska uruchomieniowego Obj-C, i to mnie zmartwiło.

--EDIT--

prostu nieco więcej informacji, w nadziei, że może pierścień dzwon z kimś ..

Kiedy próbowałem zastępując normalne obj-C wiadomość inwokację z wyraźnym zadzwoń do objc_msgSend, znalazłem to:

SEL s = sel_getUid ("init"); 
objc_msgSend (myObject, s); // Succeeds! 

SEL s = @selector (init); 
objc_msgSend (myObject, s); // Fails! 

..so wydaje się, że kiedy auto-dzyń generuje wartość SEL, to tworząc wartość nie jest użyteczny przy starcie. Czy ktoś może nawet zasugerować, gdzie powinienem szukać kodu LLVM/Clang, aby spróbować zrozumieć, co się dzieje?

+0

Czy robiłeś od tego czasu jakieś postępy? –

+0

Dla wszystkich zainteresowanych jest dyskusja na ten temat na temat LLVM dev: [Czy możliwe jest wykonanie kodu Objective-C za pomocą JIT LLVM?] (Http://lists.llvm.org/pipermail/llvm-dev/2016-November/ 106995.html). –

Odpowiedz

2

Objective-C używa specjalnie nazwanych globali, aby odnieść się do selektorów, a linker i środowisko uruchomieniowe ObjC mają specjalną wiedzę o tych globaliach, dzięki czemu wszystko działa normalnie. lli nie ma wiedzy o Objective-C; w związku z tym środowisko wykonawcze ObjC nigdy nie uruchamia specjalnego traktowania dla danych globali.

Nie mam pojęcia, co dokładnie trzeba zrobić, aby to zadziałało.

+0

Tak, podejrzewam, że to coś takiego. Dziennik debugowania poprawnie pokazuje nazwę selektora, więc struktura musi być w pewnym stopniu zainicjowana, ale może jest tam jakaś struktura klasowa, która nie jest poprawnie skonfigurowana. – jules72

Powiązane problemy