На каком языке написан Swift?

Ну, как говорится в названии, на каком языке написан Swift (язык Apple, а не другая вещь Swift)? Более конкретно, что такое написанный компилятор. Написано ли оно на языке C (как на любом другом языке) или на каком-либо другом магическом, неизвестном-тиль-сейчас суперязыке? Или это какая-то странная рекурсивная, загрузочная версия Swift? В этой проблеме нет ничего странного.

Ответы

Ответ 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 в рамках одной программы.

из быстрой википедии