Информация о вводе могла быть как-то закодирована в имени C функции; это делается C ++ и другими реализациями и называется name mangling .
Фактически, вы можете решить, поскольку весь ваш код C генерируется, принять другое соглашение: генерировать long C идентификаторов, которые являются практически уникальными и своего рода случайными для всей программы, например, tiziw_7oa7eIzzcxv03TmmZ
, и хранят свою информацию о типе в другом месте (например, в некоторой базе данных). На Linux такой подход удобен как для libbacktrace , так и для dlsym (3) + dladdr (3) (и, конечно, nm ( 1) или readelf (1) или gdb (1) ), поэтому используется в обоих проектах bismon и RefPerSys .
Информация о вводе практически привязана к соглашениям о вызовах и ABI s. Например, x86-64 ABI для Linux предписывает разные регистры процессора для передачи с плавающей запятой или указателей.
Прочтите руководство Сборка мусора или хотя бы P.Wilson Однопроцессорные методы сборки мусора опрос. Вы можете решить использовать целые числа с тегами вместо их упаковки, и вы можете решить использовать консервативное G C (например, G C Бёма) вместо точного. В моем старом проекте G CC MELT я создал код C или C ++ для генерального копирования G C. Подобные методы используются как в Bismon , так и в RefPerSys .
Поскольку вы выполняете перенос в C, рассмотрите также альтернативы, такие как libgccjit или LLVM . Посмотрите на libjit и asmjit .
Изучите также реализацию других транспиляторов (компиляторы для C), включая Chicken / Scheme и Bigloo .
Может ли компилятор G CC изменить порядок переменных в соответствии с тем, как они объявлены в исходном коде?
Конечно, да, в зависимости от запрашиваемой вами оптимизации. Некоторые переменные даже не будут существовать в двоичном коде (например, те, которые остаются в регистрах).
Могу ли я заставить компилятор поместить некоторые данные в кадр стека метода (используя volatile)?
Лучше сгенерировать одну struct
переменную, содержащую все переменные вашего языка, и оставить оптимизацию компилятору. Вы будете удивлены (см. этот черновик отчета).
Могу ли я точно определить смещение при сканировании стопки?
Это самый сложно, и зависит много от оптимизаций компилятора (например, если вы запускаете gcc
с -O1
или -O3
на сгенерированном коде C; в некоторых случаи недавнего G CC -eg G CC 9 или G CC 10 на x86-64 для Linux - может tail-call optimizations; проверьте, скомпилировав с помощью gcc -O3 -S -fverbose-asm
, а затем заглянув в созданный код ассемблера). Если вы согласны с некоторыми хитростями c, специфичными для небольшого целевого процессора и компилятора, это выполнимо. Изучите реализацию компилятора Ocaml .
Отправьте мне (на basile@starynkevitch.net
) электронное письмо для обсуждения. Пожалуйста, укажите в нем URL-адрес вашего вопроса.
Если вы хотите иметь эффективное копирование поколений G C с многопоточностью, все становится чрезвычайно сложным. Тогда возникает вопрос, сколько лет разработки вы можете себе позволить потратить.
Если у вас есть исключения в вашем языке, будьте очень осторожны. Вы можете с большой осторожностью генерировать звонки на longjmp
.
См., Конечно, этот ответ мой.
С помощью методов транспиляции зло в подробнее
На Linux (конкретно!) см. также мою manydl. c программу. Он демонстрирует, что на ноутбуке Linux x86-64 вы можете на практике сгенерировать сотни тысяч dlopen (3) -ed плагинов . Прочтите тогда Как писать разделяемые библиотеки
Изучите также реализацию SBCL и GNU Prolog , по крайней мере для вдохновения.
PS. Мечта о полностью независимом от архитектуры и операционной системе транспилере - это иллюзия.