Я работаю над игрушечным языком. Я хочу создать функцию, которая принимает функцию в качестве параметра, который она может вызвать позже. В LLVM IR это будет выглядеть так:
define i8 @foo(i8 ()* %f) {
entry:
%0 = call i8 %f()
ret i8 %0
}
Когда я попытался воссоздать это с помощью API c ++, я столкнулся с некоторыми проблемами. Я создал тип указателя типа функции i8 () *
, который я установил в качестве параметра для типа функции. Позже, когда я пытаюсь вызвать один из аргументов функции (через func->args()
), я получаю ошибку:
Assertion failed: (isa<X>(Val) && "cast<Ty>() argument of incompatible type!"), function cast
Что означает эта ошибка? Как мне реализовать это?
редактирует
Указатель функции выглядит так, когда я его печатаю (funcPtr->print(errs())
)
i8 ()* %f
Я не получаю сообщение об ошибке при загрузке указателя, но, когда я пытаюсь распечатать его, я получаю исключение неверного доступа.
Код
auto* funcPtr = namedArgs[name]; // get the function pointer from arguments
funcPtr->print(errs()); // => `i8 ()* %f`
func = (Function *)mBuilder.CreateLoad(funcPtr); // no errors
func->print(errs()); // => Exception: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
Кроме того, вот последняя функция, выведенная моим кодом, когда функция не вызывается:
define 18 @callme(i8 ()* %f) {
entry:
ret 18 0
}