LINUX.ORG.RU

История изменений

Исправление quasimoto, (текущая версия) :

я не нашёл в стандарте этому подтверждения.

Подтверждение нужно искать не этому, а существованию UB которое ты подозревал, то есть тому, что можно испортить указатель на функцию без кастов и 0-указателей, то есть как-то сделать так, чтобы он стал указывать на память по которой никакого полезного и правильного кода нет. Если ты найдёшь в стандарте описание такой возможности и соответствующее определение семантики как UB, тогда да. Иначе говоря, доказывать, что всё (∀) хорошо не нужно, нужно доказывать что не может быть плохо (¬∃, это одно и то же, но чтобы доказать первое нужно доказывать второе, то есть доказать отсутствие прецедента). Я вот не верю в существование такого прецедента (с определёнными допущениями про касты и т.п.), поэтому не вижу смысла искать в стандарте то чего там нет.

С другой стороны, во всяком JIT для C/C++ обязательно будут сильные касты, но это уже вопрос отсутствия багов (которые могут дать UB) в таком JIT и в коде его использующем.

шаблоны бывают только во время компиляции, в рантайме нет никаких шаблонов.

В статически типизированном языке то что существует во время компиляции как раз направлено на предотвращение нехороших вещей в рантайме. Например:

template <typename R, typename... A>
class function {
    typedef R(*FP)(A...);
    typedef R(&FR)(A...);
    FP fn;
  public:
    explicit function(FR fn_) : fn(fn_) {}
    R operator()(A... x) { return fn(x...); }
    void operator=(FR fn_) { fn = fn_; }
};

доступ к сегменту кода можно только через непереносимые костыли

Решаем задачу на Linux с mmap и всё у нас хорошо. Понадобилось переносимость на Windows? Пишем зависимую часть для неё и тоже решаем задачу, оставляя общим интерфейс. Например, JIT LLVM работает везде и имеет общий интерфейс.

допилить функционал eval'а не составит труда.

Ну а при наличии родного ассемблера и компилятора «не составит труда» допилить JIT. Титиретически :)

Только такого никто не делал - JIT'а прямо в код arch.

Ты про си и плюсы, да? Тогда ещё раз повторю про libJIT (это в arch из DSL на си), LLVM (это в arch из любого llvm кода), Clang (это из си и плюсов в llvm код) и загружаемые разделяемые библиотеки.

Вот пруф

Я вижу proposition, но не вижу proof. Но это не важно - речь же про реализацию _одного_ языка как байткода для VM и как JIT в машкод для CPU, а не «что угодно» vs «что угодно».

Исходная версия quasimoto, :

я не нашёл в стандарте этому подтверждения.

Подтверждение нужно искать не этому, а существованию UB которое ты подозревал, то есть тому, что можно испортить указатель на функцию без кастов и 0-указателей, то есть как-то сделать так, чтобы он стал указывать на память по которой никакого полезного и правильного кода нет. Если ты найдёшь в стандарте описание такой возможности и соответствующее определение семантики как UB, тогда да. Иначе говоря, доказывать, что всё (∀) хорошо не нужно, нужно доказывать что не может быть плохо (¬∃, это одно и то же, но чтобы доказать первое нужно доказывать второе, то есть доказать отсутствие прецедента). Я вот не верю в существование такого прецедента (с определёнными допущениями про касты и т.п.), поэтому не вижу смысла искать в стандарте то чего там нет.

С другой стороны, во всяком JIT для C/C++ обязательно будут сильные касты, но это уже вопрос отсутствия багов (которые могут дать UB) в таком JIT и в коде его использующем.

шаблоны бывают только во время компиляции, в рантайме нет никаких шаблонов.

В статически типизированном языке то что существует во время компиляции как раз направлено на предотвращение нехороших вещей в рантайме. Например:

template <typename R, typename... A>
class function {
    typedef R(*FP)(A...);
    typedef R(&FR)(A...);
    FP fn;
  public:
    explicit function(FR fn_) : fn(fn_) {}
    R operator()(A... x) { return fn(x...); }
    FP operator=(FR fn_) { return fn = fn_; }
};

доступ к сегменту кода можно только через непереносимые костыли

Решаем задачу на Linux с mmap и всё у нас хорошо. Понадобилось переносимость на Windows? Пишем зависимую часть для неё и тоже решаем задачу, оставляя общим интерфейс. Например, JIT LLVM работает везде и имеет общий интерфейс.

допилить функционал eval'а не составит труда.

Ну а при наличии родного ассемблера и компилятора «не составит труда» допилить JIT. Титиретически :)

Только такого никто не делал - JIT'а прямо в код arch.

Ты про си и плюсы, да? Тогда ещё раз повторю про libJIT (это в arch из DSL на си), LLVM (это в arch из любого llvm кода), Clang (это из си и плюсов в llvm код) и загружаемые разделяемые библиотеки.

Вот пруф

Я вижу proposition, но не вижу proof. Но это не важно - речь же про реализацию _одного_ языка как байткода для VM и как JIT в машкод для CPU, а не «что угодно» vs «что угодно».