当前(旧)函数调用签名:
long vmcall(const std::string& function_name,
std::vector<address_t> args);
现在,由于我只能使用(地址大小的)整数调用来宾,这是一个非常有限的接口,我想将其扩展为至少也处理浮点值,可能还有其他值,如下所示:
template <typename... Args>
long vmcall(const std::string& function_name,
Args&&... args);
那将是新的函数签名,取代旧的。
要显示当前如何使用 args 向量:
template <int W>
inline void Machine<W>::setup_call(
address_t call_addr, address_t retn_addr,
std::vector<address_t> args)
{
assert(args.size() <= 8);
cpu.reg(RISCV::REG_RA) = retn_addr;
for (size_t arg = 0; arg < args.size(); arg++) {
cpu.reg(RISCV::REG_ARG0 + arg) = args[arg];
}
cpu.jump(call_addr);
}
这个函数是用 std::move(args) 从 vmcall 调用的,它所做的只是将 args 向量中的整数参数以增量方式复制到整数 CPU 寄存器中。当我想调用一个只接受整数参数的函数时,这很好用。所以,如果我想调用一个函数,比如说,它接受一个浮点参数,那么就没有办法做到这一点。这是因为 FP 寄存器是完全独立的,需要区别对待。
此外,32 位和 64 位浮点数通过 NaN 装箱以不同方式处理。所以,如果能区分 float 和 double 就好了。
一开始我对模板魔法的能力并不强。如何对参数包中每个元素的类型进行分支?