current commit
260801.7 · test: reuse ffi.suffix instead of reimplementing it
'use strict';

const common = require('../common');
const fs = require('node:fs');
const path = require('node:path');

common.skipIfFFIMissing();

const { suffix } = require('node:ffi');

const fixtureBuildDir = path.join(
  __dirname,
  'fixture_library',
  'build',
  common.buildType,
);
const libraryPath = path.join(fixtureBuildDir, `ffi_test_library.${suffix}`);

function ensureFixtureLibrary() {
  if (!fs.existsSync(libraryPath)) {
    throw new Error(
      `Missing FFI test fixture library: ${libraryPath}. ` +
      'Build it first with `make build-ffi-tests` or the equivalent test build step.',
    );
  }
}

ensureFixtureLibrary();

const fixtureSymbols = {
  add_i8: { arguments: ['i8', 'i8'], return: 'i8' },
  add_u8: { arguments: ['u8', 'u8'], return: 'u8' },
  add_i16: { arguments: ['i16', 'i16'], return: 'i16' },
  add_u16: { arguments: ['u16', 'u16'], return: 'u16' },
  add_i32: { arguments: ['i32', 'i32'], return: 'i32' },
  add_u32: { arguments: ['u32', 'u32'], return: 'u32' },
  add_i64: { arguments: ['i64', 'i64'], return: 'i64' },
  add_u64: { arguments: ['u64', 'u64'], return: 'u64' },
  identity_char: { arguments: ['char'], return: 'char' },
  char_is_signed: { arguments: [], return: 'i32' },
  add_f32: { arguments: ['f32', 'f32'], return: 'f32' },
  multiply_f64: { arguments: ['f64', 'f64'], return: 'f64' },
  identity_pointer: { arguments: ['pointer'], return: 'pointer' },
  pointer_to_usize: { arguments: ['pointer'], return: 'u64' },
  usize_to_pointer: { arguments: ['u64'], return: 'pointer' },
  string_length: { arguments: ['pointer'], return: 'u64' },
  string_concat: { arguments: ['pointer', 'pointer'], return: 'pointer' },
  string_duplicate: { arguments: ['pointer'], return: 'pointer' },
  free_string: { arguments: ['pointer'], return: 'void' },
  fill_buffer: { arguments: ['pointer', 'u64', 'u32'], return: 'void' },
  sum_buffer: { arguments: ['pointer', 'u64'], return: 'u64' },
  reverse_buffer: { arguments: ['pointer', 'u64'], return: 'void' },
  logical_and: { arguments: ['i32', 'i32'], return: 'i32' },
  logical_or: { arguments: ['i32', 'i32'], return: 'i32' },
  logical_not: { arguments: ['i32'], return: 'i32' },
  increment_counter: { arguments: [], return: 'void' },
  get_counter: { arguments: [], return: 'i32' },
  reset_counter: { arguments: [], return: 'void' },
  call_int_callback: { arguments: ['pointer', 'i32'], return: 'i32' },
  call_int8_callback: { arguments: ['pointer', 'i8'], return: 'i8' },
  call_pointer_callback_is_null: { arguments: ['pointer'], return: 'i32' },
  call_void_callback: { arguments: ['pointer'], return: 'void' },
  call_string_callback: { arguments: ['function', 'pointer'], return: 'void' },
  call_binary_int_callback: { arguments: ['function', 'i32', 'i32'], return: 'i32' },
  call_callback_multiple_times: { arguments: ['pointer', 'i32'], return: 'void' },
  divide_i32: { arguments: ['i32', 'i32'], return: 'i32' },
  safe_strlen: { arguments: ['pointer'], return: 'i32' },
  sum_five_i32: { arguments: ['i32', 'i32', 'i32', 'i32', 'i32'], return: 'i32' },
  sum_five_f64: { arguments: ['f64', 'f64', 'f64', 'f64', 'f64'], return: 'f64' },
  mixed_operation: { arguments: ['i32', 'f32', 'f64', 'u32'], return: 'f64' },
  allocate_memory: { arguments: ['u64'], return: 'pointer' },
  deallocate_memory: { arguments: ['pointer'], return: 'void' },
  array_get_i32: { arguments: ['pointer', 'u64'], return: 'i32' },
  array_set_i32: { arguments: ['pointer', 'u64', 'i32'], return: 'void' },
  array_get_f64: { arguments: ['pointer', 'u64'], return: 'f64' },
  array_set_f64: { arguments: ['pointer', 'u64', 'f64'], return: 'void' },
};

if (!common.isWindows) {
  fixtureSymbols.readonly_memory = { arguments: [], return: 'pointer' };
}

function cString(value) {
  return Buffer.from(`${value}\0`);
}

module.exports = {
  cString,
  fixtureSymbols,
  libraryPath,
};