Skip to content

Commit

Permalink
Fix issue with allocating game objects on CoW memory
Browse files Browse the repository at this point in the history
  • Loading branch information
fwsGonzo committed Dec 19, 2024
1 parent ecd15a3 commit 2e613b8
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 28 deletions.
21 changes: 12 additions & 9 deletions engine/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,20 @@ int main()

/* The event_loop function can be resumed later, and can execute work
that has been preemptively handed to it from other machines. */
auto events = Script("events", "scripts/gameplay.elf", debug);
Script events("events", "scripts/gameplay.elf", debug);
/* A VM function call. The function is looked up in the symbol table
of the program binary. Without an entry in the table, we cannot
know the address of the function, even if it exists in the code. */
assert(events.address_of("event_loop") != 0x0);
events.call("event_loop");

/* Create the gameplay machine by cloning 'events' (same binary, but new instance) */
auto gameplay = events.clone("gameplay");
Script gameplay = events.clone("gameplay");

/* This is the main start function, which would be something like the
starting function for the current levels script. You can find the
implementation in scripts/src/level1.cpp. */
auto level1 = Script("level1", "scripts/level1.elf", debug);
Script level1("level1", "scripts/level1.elf", debug);
/* level1 make remote calls to the gameplay program. */
level1.setup_remote_calls_to(gameplay);

Expand All @@ -55,7 +55,7 @@ int main()
}

/* Use strict remote calls for level2 */
auto level2 = Script("level2", "scripts/level2.elf", debug);
Script level2("level2", "scripts/level2.elf", debug);
/* level2 can make remote calls to the gameplay program. */
level2.setup_strict_remote_calls_to(gameplay);
/* Allow calling *only* this function remotely, when in strict mode */
Expand Down Expand Up @@ -142,15 +142,18 @@ int main()
"Calling '", gameplay.symbol_name(obj.onDeath), "' in '",
gameplay.name(), "' for object at 0x",
strf::hex(guest_objs.address(0)), "\n");
assert(obj.alive == true);
gameplay.call(obj.onDeath, guest_objs.address(0));
assert(obj.alive == false);

/* Guest-allocated objects can be moved */
auto other_guest_objs = std::move(guest_objs);
other_guest_objs.at(0).alive = true;
gameplay.call(other_guest_objs.at(0).onDeath, other_guest_objs.address(0));
assert(other_guest_objs.at(0).alive == false);
auto other_guest_objs = std::move(guest_objs);

GameObject& other_object = other_guest_objs.at(0);
other_object.alive = true;
other_object.name = "otherobject";
other_object.onDeath = gameplay.address_of("myobject_death");
gameplay.call(other_object.onDeath, other_guest_objs.address(0));
assert(other_object.alive == false);

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

Expand Down
1 change: 0 additions & 1 deletion engine/src/script/script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ void Script::machine_setup()
const machine_t&, const char* p, size_t len) {
strf::to(stdout)(std::string_view {p, len});
});
machine().set_debug_printer(machine().get_printer());
machine().on_unhandled_csr = [](machine_t& machine, int csr, int, int)
{
auto& script = *machine.template get_userdata<Script>();
Expand Down
5 changes: 4 additions & 1 deletion engine/src/script/script.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,10 @@ template <typename T> inline GuestObjects<T> Script::guest_alloc(size_t n)
auto addr = this->guest_alloc_sequential(sizeof(T) * n);
if (addr != 0x0)
{
auto view = machine().memory.rvspan<T>(addr, n);
// Gather single writable buffer, making sure memory is not copy-on-write
std::array<riscv::vBuffer, 1> buf;
machine().memory.gather_writable_buffers_from_range(1, buf.data(), addr, sizeof(T) * n);
std::span<T> view(reinterpret_cast<T*>(buf[0].ptr), n);
// Default-initialize all objects
for (auto& o : view) o = T{};
// Note: this can fail and throw, but we don't care
Expand Down
2 changes: 1 addition & 1 deletion ext/libriscv
16 changes: 1 addition & 15 deletions programs/detect_compiler.sh
Original file line number Diff line number Diff line change
@@ -1,19 +1,5 @@
# We prefer a custom-built Newlib compiler (due to small binaries)
if command -v "riscv64-unknown-elf-g++" &> /dev/null; then
echo "* Building game scripts with Newlib RISC-V compiler"
GCC_TRIPLE="riscv64-unknown-elf"
export CXX="ccache $GCC_TRIPLE-g++"
export CEXT="OFF"

# Then, second a custom-built Linux compiler
elif command -v "riscv64-unknown-linux-gnu-g++" &> /dev/null; then
echo "* Building game scripts with custom GCC/glibc compiler"
GCC_TRIPLE="riscv64-unknown-linux-gnu"
export CXX="ccache $GCC_TRIPLE-g++"
export CEXT="OFF"

# System-provided GCC variants
elif command -v "riscv64-linux-gnu-g++-13" &> /dev/null; then
if command -v "riscv64-linux-gnu-g++-13" &> /dev/null; then
echo "* Building game scripts with system GCC/glibc compiler"
GCC_TRIPLE="riscv64-linux-gnu"
export CXX="ccache $GCC_TRIPLE-g++-13"
Expand Down
2 changes: 1 addition & 1 deletion programs/micro/api/api_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ inline void expect_check(

#define EXPECT(expr) \
api::expect_check( \
[&] \
[&] () -> bool \
{ \
return (expr); \
}, \
Expand Down

0 comments on commit 2e613b8

Please sign in to comment.