Ну, как говорится в названии, на каком языке написан Swift (язык Apple, а не другая вещь Swift)? Более конкретно, что такое написанный компилятор. Написано ли оно на языке C (как на любом другом языке) или на каком-либо другом магическом, неизвестном-тиль-сейчас суперязыке? Или это какая-то странная рекурсивная, загрузочная версия Swift? В этой проблеме нет ничего странного.
На каком языке написан Swift?
Ответ 1
Исходный код только что был выпущен в Github, и кажется, что сам Swift в основном написан на C++, а его стандартная библиотека написана в Swift.
Для получения дополнительной информации см. Этот пресс-релиз от Apple и новый веб-сайт Swift.org.
Ответ 2
Swift реализуется на C. Вы можете увидеть обзор анализа одного человека здесь: https://github.com/rodionovd/SWRoute/wiki/Function-hooking-in-Swift
С Swift, идущим с открытым исходным кодом, я полагаю, что на этот вопрос будет дан ответ более полно в этот момент.
Я включу часть ниже, но обязательно прочитаю весь анализ, если вам интересно:
func call_function(f : () -> Int) {
let b = f()
}
func someFunction() -> Int {
return 0
}
В Swift мы просто пишем call_function (someFunction). Но вместо выполнения вызова как call_function (& someFunction), Swift-компилятор создает код:
struct swift_func_wrapper *wrapper = ... /* configure wrapper for someFunction() */
struct swift_func_type_metadata *type_metadata = ... /* information about function arguments and return type */
call_function(wrapper->trampoline, type_metadata);
Обертка имеет следующую структуру:
struct swift_func_wrapper {
uint64_t **trampoline_ptr_ptr; // = &trampoline_ptr
uint64_t *trampoline_ptr;
struct swift_func_object *object;
}
И какой тип swift_func_object? Чтобы создать этот объект, среда выполнения Swift использует глобальную константу с именем metadata [N] (которая уникальна для каждого вызова функции, которая принимает ваш func как аргумент родового типа, поэтому для этого кода:
func callf(f: () -> ()) {
f();
}
callf(someFunction);
callf(someFunction);
будут созданы две метаданные констант и метаданные2).
Структура метаданных [N] выглядит следующим образом:
struct metadata {
uint64_t *destructor_func;
uint64_t *unknown0;
const char type:1; // I'm not sure about this and padding,
char padding[7]; // maybe it just a uint64_t too...
uint64_t *self;
}
Первоначально metadataN имеет только два поля: destructor_func и type. Первый - это указатель на функцию, которая будет использоваться для освобождения всей памяти для объекта, созданного с помощью swift_allocObject(). И последний является идентификатором типа объекта (0x40 или "@" для функций/методов) и (каким-то образом) используется swift_allocObject() для создания правильного объекта для нашей функции:
swift_allocObject(&metadata2->type, 0x20, 0x7);
Когда объект func создается, он имеет следующую структуру:
struct swift_func_object {
uint64_t *original_type_ptr;
uint64_t *unknown0;
uint64_t function_address;
uint64_t *self;
}
Первое поле является указателем на соответствующее значение метаданных [N] → type, второе - 0x4 | 1 << 24 (0x100000004), и это указывает что-то, может быть (не знаю, что). function_address - это то, что мы действительно заинтересованы в подключении, а self (внезапно) - указатель на себя (если наш объект представляет собой обычную функцию, это поле NULL).
Ответ 3
Он построен с использованием компилятора LLVM, включенного в Xcode 6, и использует время выполнения Objective-C, позволяя запускать C, Objective-C, C++ и Swift в рамках одной программы.