Skip to content

Commit

Permalink
Add unit test for dynamic calls with arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
fwsGonzo committed Jan 14, 2024
1 parent d4e4a0f commit 12e2dbe
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 98 deletions.
39 changes: 0 additions & 39 deletions engine/scripts/src/gameplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,32 +45,6 @@ static void inline_dyncall_handler()
return_fast();
}

static void opaque_dyncall_args_x4()
{
sys_empty();
sys_testing123(4, 5, 6, 7.0f, 8.0f, 9.0f);
sys_empty();
sys_testing123(4, 5, 6, 7.0f, 8.0f, 9.0f);
sys_empty();
sys_testing123(4, 5, 6, 7.0f, 8.0f, 9.0f);
sys_empty();
sys_testing123(4, 5, 6, 7.0f, 8.0f, 9.0f);
return_fast();
}

static void inline_dyncall_args_x4()
{
isys_empty();
isys_testing123(4, 5, 6, 7.0, 8.0, 9.0);
isys_empty();
isys_testing123(4, 5, 6, 7.0, 8.0, 9.0);
isys_empty();
isys_testing123(4, 5, 6, 7.0, 8.0, 9.0);
isys_empty();
isys_testing123(4, 5, 6, 7.0, 8.0, 9.0);
return_fast();
}

PUBLIC(void public_donothing())
{
/* nothing */
Expand Down Expand Up @@ -101,8 +75,6 @@ PUBLIC(void benchmarks())
measure("Direct thread creation overhead", direct_thread_function);
measure("Dynamic call handler x4 (inline)", inline_dyncall_handler);
measure("Dynamic call handler x4 (call)", opaque_dyncall_handler);
measure("Dynamic call args x8 (inline)", inline_dyncall_args_x4);
measure("Dynamic call args x8 (call)", opaque_dyncall_args_x4);

//benchmark_multiprocessing();
}
Expand Down Expand Up @@ -140,14 +112,3 @@ PUBLIC(void myobject_death(GameObject& object))
/* SFX: Ugh... */
object.alive = false;
}

PUBLIC(void test_dynamic_functions())
{
// See: dynamic_calls.json
// 1: A simple no-argument dynamic call
sys_testing();
// 2: A dynamic call that takes a zero-terminated string, and then a string with length
sys_testing_strings("Hello World!", "Hello World!", 12);
// 3: A dynamic call that takes a few integers and floats
sys_testing123(4, 5, 6, 7.0, 8.0, 9.0);
}
55 changes: 0 additions & 55 deletions engine/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,47 +155,6 @@ int main()

strf::to(stdout)("...\n");

/* Verify dynamic functions are working */
int called = 0x0;
gameplay.set_dynamic_call(
"void sys_testing ()",
[&](auto&)
{
called |= 0x1;
});
gameplay.set_dynamic_call(
"void sys_testing_strings (const char*, const char*, size_t)",
[&](auto& s)
{
// Argument 1: A heap-allocated string
// Argument 2: A string-view pointing into guest memory
const auto [str, view]
= s.machine().template sysargs<std::string, std::string_view>();
if (str == "Hello World!" && view == "Hello World!")
{
called |= 0x2;
}
});
gameplay.set_dynamic_call(
"void sys_testing123 (int, int, int, float, float, float)",
[&](auto& s)
{
const auto [arg1, arg2, arg3, arg4, arg5, arg6]
= s.machine().template sysargs<int, int, int, float, float, float>();
if (arg1 == 4 && arg2 == 5 && arg3 == 6 && arg4 == 7.0 && arg5 == 8.0 && arg6 == 9.0)
{
called |= 0x4;
}
});
gameplay.call("test_dynamic_functions");
// All the functions should have been called
if (called != (0x1 | 0x2 | 0x4)) {
strf::to(stderr)(
"Error: Dynamic calls not invoked or did not set locals!?\n");
exit(1);
}

strf::to(stdout)("* Dynamic call tests passed!\n");

if (Script::get_global_setting("benchmarks").value_or(false))
{
Expand All @@ -204,20 +163,6 @@ int main()

// Benchmarks of various features
gameplay.call("benchmarks");

// Fork benchmarks
strf::to(stdout)("Benchmarking RISC-V machine fork:\n");
Script::benchmark(
[&gameplay]
{
// Forking the underlying virtual machine
const riscv::MachineOptions<Script::MARCH> options {
.memory_max = 16ULL << 20,
.stack_size = 2ULL << 20,
.use_memory_arena = true
};
riscv::Machine<Script::MARCH> fork { gameplay.machine(), options };
});
}

strf::to(stdout)("...\nBringing up the main screen!\n");
Expand Down
12 changes: 12 additions & 0 deletions engine/src/script/script.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ struct Script
void dynamic_call_hash(uint32_t hash, gaddr_t strname);
void dynamic_call_array(uint32_t idx);

/// @brief Retrieve arguments passed to a dynamic call, specifying each type.
/// @tparam ...Args The types of arguments to retrieve.
/// @return A tuple of arguments.
template <typename... Args>
auto args() const;

auto& dynargs()
{
return m_arguments;
Expand Down Expand Up @@ -383,6 +389,12 @@ inline void Script::resume(uint64_t cycles)
}
}

template <typename... Args>
inline auto Script::args() const
{
return machine().sysargs<Args ...> ();
}

/**
* This uses RAII to sequentially allocate a range
* for the objects, which is freed on destruction.
Expand Down
7 changes: 3 additions & 4 deletions programs/dynamic_calls.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
"GUI::widget_set_pos": "void sys_gui_widget_set_pos (unsigned, int, int)",
"GUI::widget_callback": "void sys_gui_widget_callback (unsigned, gui_callback, void *, size_t)",

"empty": "void sys_empty ()",
"testing": "void sys_testing ()",
"testing_strings": "void sys_testing_strings (const char*, const char*, size_t)",
"testing123": "void sys_testing123 (int, int, int, float, float, float)"
"empty": "void sys_empty ()",
"test_string": "void sys_test_strings (const char*, const char*, size_t)",
"test_3i_3f": "void sys_test_3i3f (int, int, int, float, float, float)"
}
53 changes: 53 additions & 0 deletions tests/basic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,56 @@ TEST_CASE("Verify late dynamic calls work", "[Basic]")
REQUIRE(ret == 666);
REQUIRE(count == 2);
}

TEST_CASE("Verify dynamic calls with arguments", "[Basic]")
{
const auto program = build_and_load(R"M(
#include <api.h>
extern "C" void test_strings() {
sys_test_strings("1234", "45678", 5);
}
extern "C" void test_args() {
sys_test_3i3f(123, 456, 789, 10.0f, 100.0f, 1000.0f);
}
int main() {
})M");

int strings_called = 0;
int args_called = 0;

Script::set_dynamic_call("void sys_test_strings (const char*, const char*, size_t)",
[&] (Script& script) {
auto [str, view] = script.args<std::string, std::string_view> ();
REQUIRE(str == "1234");
REQUIRE(view == "45678");
strings_called += 1;
});
Script::set_dynamic_call("void sys_test_3i3f (int, int, int, float, float, float)",
[&] (Script& script) {
auto [i1, i2, i3, f1, f2, f3] = script.args<int, int, int, float, float, float> ();
REQUIRE(i1 == 123);
REQUIRE(i2 == 456);
REQUIRE(i3 == 789);
REQUIRE(f1 == 10.0f);
REQUIRE(f2 == 100.0f);
REQUIRE(f3 == 1000.0f);
args_called += 1;
});

Script script {program, "MyScript", "/tmp/myscript"};

REQUIRE(strings_called == 0);
REQUIRE(args_called == 0);

script.call("test_strings");

REQUIRE(strings_called == 1);
REQUIRE(args_called == 0);

script.call("test_args");

REQUIRE(strings_called == 1);
REQUIRE(args_called == 1);
}

0 comments on commit 12e2dbe

Please sign in to comment.