niftest.zig 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. const erl = @cImport({
  2. @cInclude("erl_nif.h");
  3. });
  4. pub export fn hello(env: ?*erl.ErlNifEnv, argc: c_int, argv: [*c]const erl.ERL_NIF_TERM) erl.ERL_NIF_TERM{
  5. _ = argv;
  6. _ = argc;
  7. //const ERL_NIF_LATIN1 = @as(c_uint, 1);
  8. return erl.enif_make_string(env, "Hello world!", 1); // ERL_NIF_LATIN1);
  9. }
  10. pub export fn factorial1(env: ?*erl.ErlNifEnv, argc: c_int, argv: [*c]const erl.ERL_NIF_TERM) erl.ERL_NIF_TERM{
  11. if(argc != 1){
  12. return erl.enif_make_badarg(env);
  13. }
  14. var n: c_long = undefined;
  15. if(erl.enif_get_long(env, argv[0], &n) == 0 or n < 0){
  16. return erl.enif_make_badarg(env);
  17. }
  18. if(n > 34){ // max n for max factorial for u128
  19. return erl.enif_make_tuple2(env,
  20. erl.enif_make_atom(env, "error"),
  21. erl.enif_make_string(env, "input too large, max is 34", 1)
  22. );
  23. }
  24. var result: u128 = 1;
  25. var i = @as(u128, @intCast(n) );
  26. //var i = n;
  27. while(i > 1) : (i -= 1){
  28. result *= i;
  29. }
  30. var num_bytes: usize = 1;
  31. var temp = result;
  32. while(temp > 255) : (temp >>= 8){
  33. num_bytes += 1;
  34. }
  35. var bin: erl.ErlNifBinary = undefined; // for return binary in big-endian
  36. if(erl.enif_alloc_binary(num_bytes, &bin) == 0){
  37. return erl.enif_make_badarg(env); // alloc faild
  38. }
  39. temp = result;
  40. var idx = num_bytes;
  41. while(idx > 0) : (idx -= 1){
  42. bin.data[idx - 1] = @as(u8, @intCast(temp & 0xFF) );
  43. temp >>= 8;
  44. }
  45. return erl.enif_make_binary(env, &bin);
  46. }
  47. const nif_funcs = [_]erl.ErlNifFunc{
  48. .{
  49. .name = "hello",
  50. .arity = 0,
  51. .fptr = hello,
  52. .flags = 0,
  53. },
  54. .{
  55. .name = "factorial1",
  56. .arity = 1,
  57. .fptr = factorial1,
  58. .flags = 0,
  59. },
  60. };
  61. export fn nif_init() ?*erl.ErlNifEntry{
  62. return &nif_entry;
  63. }
  64. var nif_entry: erl.ErlNifEntry = .{
  65. .major = 2,
  66. .minor = 16,
  67. .name = "niftest",
  68. .num_of_funcs = nif_funcs.len,
  69. .funcs = @constCast(&nif_funcs),
  70. .load = null,
  71. .reload = null,
  72. .upgrade = null,
  73. .unload = null,
  74. .vm_variant = "beam.vanilla",
  75. .options = 1, // 0,
  76. .sizeof_ErlNifResourceTypeInit = @sizeOf(erl.ErlNifResourceTypeInit),
  77. .min_erts = "erts-12.0", // .entry_version = 3,
  78. };