Skip to content

Commit

Permalink
Merge pull request #112 from membraneframework/missing_types
Browse files Browse the repository at this point in the history
implement uint64 & int64 types for cNode
  • Loading branch information
bartkrak authored Mar 11, 2024
2 parents 6a9ae37 + 12e9c15 commit 0edf54e
Show file tree
Hide file tree
Showing 11 changed files with 232 additions and 7 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ defmodule MyApp.Mixfile do

defp deps() do
[
{:unifex, "~>> 1.1.2"}
{:unifex, "~>> 1.2.0"}
]
end
end
Expand Down
24 changes: 23 additions & 1 deletion lib/unifex/code_generator/base_types/int64.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule Unifex.CodeGenerator.BaseTypes.Int64 do
Maps `int64` Unifex type to an `int64_t` native type.
Implemented only for NIF as function parameter as well as return type.
Implemented both for NIF and CNode as function parameter as well as return type.
"""
use Unifex.CodeGenerator.BaseType

Expand All @@ -27,4 +27,26 @@ defmodule Unifex.CodeGenerator.BaseTypes.Int64 do
})>
end
end

defmodule CNode do
@moduledoc false
use Unifex.CodeGenerator.BaseType

@impl true
def generate_arg_parse(argument, name, _ctx) do
~g"""
({
long long tmp_longlong;
int result = ei_decode_longlong(#{argument}->buff, #{argument}->index, &tmp_longlong);
#{name} = (int64_t)tmp_longlong;
result;
})
"""
end

@impl true
def generate_arg_serialize(name, _ctx) do
~g<ei_x_encode_longlong(out_buff, (long long)#{name});>
end
end
end
24 changes: 23 additions & 1 deletion lib/unifex/code_generator/base_types/uint64.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,34 @@ defmodule Unifex.CodeGenerator.BaseTypes.Uint64 do
Maps `uint64` Unifex type to a `uint64_t` native type.
Implemented only for NIF as function parameter as well as return type.
Implemented both for NIF and CNode as function parameter as well as return type.
"""
use Unifex.CodeGenerator.BaseType

@impl true
def generate_native_type(_ctx) do
~g<uint64_t>
end

defmodule CNode do
@moduledoc false
use Unifex.CodeGenerator.BaseType

@impl true
def generate_arg_parse(argument, name, _ctx) do
~g"""
({
unsigned long long tmp_ulonglong;
int result = ei_decode_ulonglong(#{argument}->buff, #{argument}->index, &tmp_ulonglong);
#{name} = (uint64_t)tmp_ulonglong;
result;
})
"""
end

@impl true
def generate_arg_serialize(name, _ctx) do
~g<ei_x_encode_ulonglong(out_buff, (long long)#{name});>
end
end
end
3 changes: 1 addition & 2 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
defmodule Unifex.MixProject do
use Mix.Project

@version "1.1.2"

@version "1.2.0"
@github_url "https://github.com/membraneframework/unifex"

def project do
Expand Down
4 changes: 2 additions & 2 deletions pages/supported_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ state of work on remaining types.
| `atom` | `char *` |||||
| `bool` | `int` |||||
| `unsigned` | `unsigned int` |||||
| `uint64` | `uint64_t` ||| | |
| `uint64` | `uint64_t` ||| | |
| `int` | `int` |||||
| `int64` | `int64_t` ||| | |
| `int64` | `int64_t` ||| | |
| `float` | `double` |||||
| `payload` | `UnifexPayload` |||||
| `pid` | `UnifexPid` |||||
Expand Down
75 changes: 75 additions & 0 deletions test/fixtures/cnode_ref_generated/cnode/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,28 @@ UNIFEX_TERM test_uint_result_ok(UnifexEnv *env, unsigned int out_uint) {
return out_buff;
}

UNIFEX_TERM test_uint64_result_ok(UnifexEnv *env, uint64_t out_uint64) {
UNIFEX_TERM out_buff = (ei_x_buff *)malloc(sizeof(ei_x_buff));
unifex_cnode_prepare_ei_x_buff(env, out_buff, "result");

ei_x_encode_tuple_header(out_buff, 2);
ei_x_encode_atom(out_buff, "ok");
ei_x_encode_ulonglong(out_buff, (long long)out_uint64);

return out_buff;
}

UNIFEX_TERM test_int64_result_ok(UnifexEnv *env, int64_t out_int64) {
UNIFEX_TERM out_buff = (ei_x_buff *)malloc(sizeof(ei_x_buff));
unifex_cnode_prepare_ei_x_buff(env, out_buff, "result");

ei_x_encode_tuple_header(out_buff, 2);
ei_x_encode_atom(out_buff, "ok");
ei_x_encode_longlong(out_buff, (long long)out_int64);

return out_buff;
}

UNIFEX_TERM test_string_result_ok(UnifexEnv *env, char const *out_string) {
UNIFEX_TERM out_buff = (ei_x_buff *)malloc(sizeof(ei_x_buff));
unifex_cnode_prepare_ei_x_buff(env, out_buff, "result");
Expand Down Expand Up @@ -537,6 +559,55 @@ UNIFEX_TERM test_uint_caller(UnifexEnv *env, UnifexCNodeInBuff *in_buff) {
return result;
}

UNIFEX_TERM test_uint64_caller(UnifexEnv *env, UnifexCNodeInBuff *in_buff) {
UNIFEX_MAYBE_UNUSED(in_buff);
UNIFEX_TERM result;
uint64_t in_uint64;

if (({
unsigned long long tmp_ulonglong;
int result =
ei_decode_ulonglong(in_buff->buff, in_buff->index, &tmp_ulonglong);
in_uint64 = (uint64_t)tmp_ulonglong;
result;
})) {
result = unifex_raise(
env,
"Unifex CNode: cannot parse argument 'in_uint64' of type ':uint64'");
goto exit_test_uint64_caller;
}

result = test_uint64(env, in_uint64);
goto exit_test_uint64_caller;
exit_test_uint64_caller:

return result;
}

UNIFEX_TERM test_int64_caller(UnifexEnv *env, UnifexCNodeInBuff *in_buff) {
UNIFEX_MAYBE_UNUSED(in_buff);
UNIFEX_TERM result;
int64_t in_int64;

if (({
long long tmp_longlong;
int result =
ei_decode_longlong(in_buff->buff, in_buff->index, &tmp_longlong);
in_int64 = (int64_t)tmp_longlong;
result;
})) {
result = unifex_raise(
env, "Unifex CNode: cannot parse argument 'in_int64' of type ':int64'");
goto exit_test_int64_caller;
}

result = test_int64(env, in_int64);
goto exit_test_int64_caller;
exit_test_int64_caller:

return result;
}

UNIFEX_TERM test_string_caller(UnifexEnv *env, UnifexCNodeInBuff *in_buff) {
UNIFEX_MAYBE_UNUSED(in_buff);
UNIFEX_TERM result;
Expand Down Expand Up @@ -1699,6 +1770,10 @@ UNIFEX_TERM unifex_cnode_handle_message(UnifexEnv *env, char *fun_name,
return test_float_caller(env, in_buff);
} else if (strcmp(fun_name, "test_uint") == 0) {
return test_uint_caller(env, in_buff);
} else if (strcmp(fun_name, "test_uint64") == 0) {
return test_uint64_caller(env, in_buff);
} else if (strcmp(fun_name, "test_int64") == 0) {
return test_int64_caller(env, in_buff);
} else if (strcmp(fun_name, "test_string") == 0) {
return test_string_caller(env, in_buff);
} else if (strcmp(fun_name, "test_list") == 0) {
Expand Down
75 changes: 75 additions & 0 deletions test/fixtures/cnode_ref_generated/cnode/example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,28 @@ UNIFEX_TERM test_uint_result_ok(UnifexEnv *env, unsigned int out_uint) {
return out_buff;
}

UNIFEX_TERM test_uint64_result_ok(UnifexEnv *env, uint64_t out_uint64) {
UNIFEX_TERM out_buff = (ei_x_buff *)malloc(sizeof(ei_x_buff));
unifex_cnode_prepare_ei_x_buff(env, out_buff, "result");

ei_x_encode_tuple_header(out_buff, 2);
ei_x_encode_atom(out_buff, "ok");
ei_x_encode_ulonglong(out_buff, (long long)out_uint64);

return out_buff;
}

UNIFEX_TERM test_int64_result_ok(UnifexEnv *env, int64_t out_int64) {
UNIFEX_TERM out_buff = (ei_x_buff *)malloc(sizeof(ei_x_buff));
unifex_cnode_prepare_ei_x_buff(env, out_buff, "result");

ei_x_encode_tuple_header(out_buff, 2);
ei_x_encode_atom(out_buff, "ok");
ei_x_encode_longlong(out_buff, (long long)out_int64);

return out_buff;
}

UNIFEX_TERM test_string_result_ok(UnifexEnv *env, char const *out_string) {
UNIFEX_TERM out_buff = (ei_x_buff *)malloc(sizeof(ei_x_buff));
unifex_cnode_prepare_ei_x_buff(env, out_buff, "result");
Expand Down Expand Up @@ -537,6 +559,55 @@ UNIFEX_TERM test_uint_caller(UnifexEnv *env, UnifexCNodeInBuff *in_buff) {
return result;
}

UNIFEX_TERM test_uint64_caller(UnifexEnv *env, UnifexCNodeInBuff *in_buff) {
UNIFEX_MAYBE_UNUSED(in_buff);
UNIFEX_TERM result;
uint64_t in_uint64;

if (({
unsigned long long tmp_ulonglong;
int result =
ei_decode_ulonglong(in_buff->buff, in_buff->index, &tmp_ulonglong);
in_uint64 = (uint64_t)tmp_ulonglong;
result;
})) {
result = unifex_raise(
env,
"Unifex CNode: cannot parse argument 'in_uint64' of type ':uint64'");
goto exit_test_uint64_caller;
}

result = test_uint64(env, in_uint64);
goto exit_test_uint64_caller;
exit_test_uint64_caller:

return result;
}

UNIFEX_TERM test_int64_caller(UnifexEnv *env, UnifexCNodeInBuff *in_buff) {
UNIFEX_MAYBE_UNUSED(in_buff);
UNIFEX_TERM result;
int64_t in_int64;

if (({
long long tmp_longlong;
int result =
ei_decode_longlong(in_buff->buff, in_buff->index, &tmp_longlong);
in_int64 = (int64_t)tmp_longlong;
result;
})) {
result = unifex_raise(
env, "Unifex CNode: cannot parse argument 'in_int64' of type ':int64'");
goto exit_test_int64_caller;
}

result = test_int64(env, in_int64);
goto exit_test_int64_caller;
exit_test_int64_caller:

return result;
}

UNIFEX_TERM test_string_caller(UnifexEnv *env, UnifexCNodeInBuff *in_buff) {
UNIFEX_MAYBE_UNUSED(in_buff);
UNIFEX_TERM result;
Expand Down Expand Up @@ -1699,6 +1770,10 @@ UNIFEX_TERM unifex_cnode_handle_message(UnifexEnv *env, char *fun_name,
return test_float_caller(env, in_buff);
} else if (strcmp(fun_name, "test_uint") == 0) {
return test_uint_caller(env, in_buff);
} else if (strcmp(fun_name, "test_uint64") == 0) {
return test_uint64_caller(env, in_buff);
} else if (strcmp(fun_name, "test_int64") == 0) {
return test_int64_caller(env, in_buff);
} else if (strcmp(fun_name, "test_string") == 0) {
return test_string_caller(env, in_buff);
} else if (strcmp(fun_name, "test_list") == 0) {
Expand Down
6 changes: 6 additions & 0 deletions test/fixtures/cnode_ref_generated/cnode/example.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ UNIFEX_TERM test_atom(UnifexEnv *env, char *in_atom);
UNIFEX_TERM test_bool(UnifexEnv *env, int in_bool);
UNIFEX_TERM test_float(UnifexEnv *env, double in_float);
UNIFEX_TERM test_uint(UnifexEnv *env, unsigned int in_uint);
UNIFEX_TERM test_uint64(UnifexEnv *env, uint64_t in_uint64);
UNIFEX_TERM test_int64(UnifexEnv *env, int64_t in_int64);
UNIFEX_TERM test_string(UnifexEnv *env, char *in_string);
UNIFEX_TERM test_list(UnifexEnv *env, int *in_list,
unsigned int in_list_length);
Expand All @@ -122,6 +124,8 @@ UNIFEX_TERM test_atom_result_ok(UnifexEnv *env, char const *out_atom);
UNIFEX_TERM test_bool_result_ok(UnifexEnv *env, int out_bool);
UNIFEX_TERM test_float_result_ok(UnifexEnv *env, double out_float);
UNIFEX_TERM test_uint_result_ok(UnifexEnv *env, unsigned int out_uint);
UNIFEX_TERM test_uint64_result_ok(UnifexEnv *env, uint64_t out_uint64);
UNIFEX_TERM test_int64_result_ok(UnifexEnv *env, int64_t out_int64);
UNIFEX_TERM test_string_result_ok(UnifexEnv *env, char const *out_string);
UNIFEX_TERM test_list_result_ok(UnifexEnv *env, int const *out_list,
unsigned int out_list_length);
Expand Down Expand Up @@ -151,6 +155,8 @@ UNIFEX_TERM test_atom_caller(UnifexEnv *env, UnifexCNodeInBuff *in_buff);
UNIFEX_TERM test_bool_caller(UnifexEnv *env, UnifexCNodeInBuff *in_buff);
UNIFEX_TERM test_float_caller(UnifexEnv *env, UnifexCNodeInBuff *in_buff);
UNIFEX_TERM test_uint_caller(UnifexEnv *env, UnifexCNodeInBuff *in_buff);
UNIFEX_TERM test_uint64_caller(UnifexEnv *env, UnifexCNodeInBuff *in_buff);
UNIFEX_TERM test_int64_caller(UnifexEnv *env, UnifexCNodeInBuff *in_buff);
UNIFEX_TERM test_string_caller(UnifexEnv *env, UnifexCNodeInBuff *in_buff);
UNIFEX_TERM test_list_caller(UnifexEnv *env, UnifexCNodeInBuff *in_buff);
UNIFEX_TERM test_list_of_strings_caller(UnifexEnv *env,
Expand Down
9 changes: 9 additions & 0 deletions test_projects/cnode/c_src/example/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ UNIFEX_TERM init(UnifexEnv *env) {
return res;
}

UNIFEX_TERM test_uint64(UnifexEnv *env, uint64_t in_uint64) {
return test_uint64_result_ok(env, in_uint64);
}

UNIFEX_TERM test_int64(UnifexEnv *env, int64_t in_int64) {
return test_int64_result_ok(env, in_int64);
}


UNIFEX_TERM test_nil(UnifexEnv* env) {
return test_nil_result_nil(env);
}
Expand Down
4 changes: 4 additions & 0 deletions test_projects/cnode/c_src/example/example.spec.exs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ spec test_float(in_float :: float) :: {:ok :: label, out_float :: float}

spec test_uint(in_uint :: unsigned) :: {:ok :: label, out_uint :: unsigned}

spec test_uint64(in_uint64 :: uint64) :: {:ok :: label, out_uint64 :: uint64}

spec test_int64(in_int64 :: int64) :: {:ok :: label, out_int64 :: int64}

spec test_string(in_string :: string) :: {:ok :: label, out_string :: string}

spec test_list(in_list :: [int]) :: {:ok :: label, out_list :: [int]}
Expand Down
13 changes: 13 additions & 0 deletions test_projects/cnode/test/example_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ defmodule ExampleTest do
[cnode: cnode]
end

test "uint64", context do
assert {:ok, 0} = Unifex.CNode.call(context[:cnode], :test_uint64, [0])
# max uint64 value
assert {:ok, 18446744073709551615} = Unifex.CNode.call(context[:cnode], :test_uint64, [18446744073709551615])
end

test "int64", context do
assert {:ok, 0} = Unifex.CNode.call(context[:cnode], :test_int64, [0])
# max int64 value
assert {:ok, 9223372036854775807} = Unifex.CNode.call(context[:cnode], :test_int64, [9223372036854775807])
assert {:ok, -9223372036854775807} = Unifex.CNode.call(context[:cnode], :test_int64, [-9223372036854775807])
end

test "nil", context do
assert nil == Unifex.CNode.call(context[:cnode], :test_nil, [])
end
Expand Down

0 comments on commit 0edf54e

Please sign in to comment.