Ответ 1
В компиляторе OCaml уже существует механизм для обмена некоторыми константами: см. asmcomp/compilenv.ml
и его использование, в частности значения structured_constants
, в asmcomp/cmmgen.ml
. Я не знаком с этим кодом, поэтому не знаю, почему ваш конкретный вариант использования не является общим, но похоже, что существует разница между лямбда-кодом, Const_base (Const_string foo)
и Const_immstring foo
; более поздние являются общими, и, возможно, первые не являются.
Я не знаю, что подразумеваемая семантика для immstring
. Кажется, он используется компилятором для компиляции меток метода (bytecomp/translclass.ml
), но не подвергается языку ввода.
(Я подозреваю, что это различие состоит в том, что строки изменяемы, поэтому совместное использование видимых пользователем строк будет наблюдаемым и изменяет поведение программ. Но строковые константы уже сняты лямбда, так что пользователи уже могут наблюдать семантически несогласованный обмен. видимые строки, вероятно, все еще будут отвергнуты как разрыв совместимости.)
Рассматривая, как эти непосредственные строки обрабатываются постоянным испускающим кодом (asmcomp/cmmgen.ml:emit_constant
), они представляются как обычные строки, поэтому, возможно, вы можете просто исправить компилятор, чтобы использовать immstring
в assert_failed
и все будет работать.
[EDIT BY OP]
Изменение Const_base (Const_string fname)
на Const_immstring fname
, хотя и немного несовместимо, позволяет OCaml скомпилировать себя, скомпилировать Frama-C, а новый Frama-C передает свои регрессионные тесты. В исходном примере эффект следующий: это был желаемый результат:
$ cat longfilename.s
...
.data
.quad 3072
_camlLongfilename__2:
.quad L100005
.quad 9
.quad 9
.data
.quad 3072
_camlLongfilename__3:
.quad L100005
.quad 7
.quad 9
.data
.quad 3072
_camlLongfilename__4:
.quad L100005
.quad 5
.quad 9
.quad 2300
L100005: .L100005:
.ascii "longfilename.ml"
.byte 0