AtomVM
AtomVM copied to clipboard
Handle functions with more than nine parameters
atom.c
static unsigned get_arity_magnitude(int n) {
unsigned magnitude = 0;
for (int i = n; i >= 1; i /= 10) {
magnitude++;
}
if (n == 0)
return 1;
return magnitude;
}
static void arity_to_str(int n, unsigned magnitude, char *ptr) {
for (int i = magnitude - 1; i >= 0; i--) {
ptr[i] = '0' + n % 10;
n /= 10;
}
ptr[magnitude] = '\0';
}
void atom_write_mfa(char *buf, size_t buf_size, AtomString module, AtomString function, unsigned int arity)
{
size_t module_name_len = atom_string_len(module);
memcpy(buf, atom_string_data(module), module_name_len);
buf[module_name_len] = ':';
int arity_magnitude = get_arity_magnitude(arity);
size_t function_name_len = atom_string_len(function);
if (UNLIKELY((module_name_len + function_name_len + arity_magnitude + 3 > buf_size))) {
fprintf(stderr, "Insufficient room to write mfa.\n");
AVM_ABORT();
}
memcpy(buf + module_name_len + 1, atom_string_data(function), function_name_len);
buf[module_name_len + function_name_len + 1] = '/';
arity_to_str(arity, arity_magnitude, buf + module_name_len + function_name_len + 2);
}
nifs.c
const struct Nif *nifs_get(AtomString module, AtomString function, int arity)
{
char nifname[MAX_NIF_NAME_LEN];
atom_write_mfa(nifname, MAX_NIF_NAME_LEN, module, function, arity);
const NifNameAndNifPtr *nameAndPtr = nif_in_word_set(nifname, strlen(nifname));
if (!nameAndPtr) {
return platform_nifs_get_nif(nifname);
}
return nameAndPtr->nif;
}