Skip to content

Commit 2e613b8

Browse files
committed
Fix issue with allocating game objects on CoW memory
1 parent ecd15a3 commit 2e613b8

File tree

6 files changed

+19
-28
lines changed

6 files changed

+19
-28
lines changed

engine/src/main.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,20 @@ int main()
3232

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

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

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

@@ -55,7 +55,7 @@ int main()
5555
}
5656

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

149148
/* Guest-allocated objects can be moved */
150-
auto other_guest_objs = std::move(guest_objs);
151-
other_guest_objs.at(0).alive = true;
152-
gameplay.call(other_guest_objs.at(0).onDeath, other_guest_objs.address(0));
153-
assert(other_guest_objs.at(0).alive == false);
149+
auto other_guest_objs = std::move(guest_objs);
150+
151+
GameObject& other_object = other_guest_objs.at(0);
152+
other_object.alive = true;
153+
other_object.name = "otherobject";
154+
other_object.onDeath = gameplay.address_of("myobject_death");
155+
gameplay.call(other_object.onDeath, other_guest_objs.address(0));
156+
assert(other_object.alive == false);
154157

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

engine/src/script/script.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ void Script::machine_setup()
152152
const machine_t&, const char* p, size_t len) {
153153
strf::to(stdout)(std::string_view {p, len});
154154
});
155-
machine().set_debug_printer(machine().get_printer());
156155
machine().on_unhandled_csr = [](machine_t& machine, int csr, int, int)
157156
{
158157
auto& script = *machine.template get_userdata<Script>();

engine/src/script/script.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,10 @@ template <typename T> inline GuestObjects<T> Script::guest_alloc(size_t n)
545545
auto addr = this->guest_alloc_sequential(sizeof(T) * n);
546546
if (addr != 0x0)
547547
{
548-
auto view = machine().memory.rvspan<T>(addr, n);
548+
// Gather single writable buffer, making sure memory is not copy-on-write
549+
std::array<riscv::vBuffer, 1> buf;
550+
machine().memory.gather_writable_buffers_from_range(1, buf.data(), addr, sizeof(T) * n);
551+
std::span<T> view(reinterpret_cast<T*>(buf[0].ptr), n);
549552
// Default-initialize all objects
550553
for (auto& o : view) o = T{};
551554
// Note: this can fail and throw, but we don't care

ext/libriscv

programs/detect_compiler.sh

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,5 @@
1-
# We prefer a custom-built Newlib compiler (due to small binaries)
2-
if command -v "riscv64-unknown-elf-g++" &> /dev/null; then
3-
echo "* Building game scripts with Newlib RISC-V compiler"
4-
GCC_TRIPLE="riscv64-unknown-elf"
5-
export CXX="ccache $GCC_TRIPLE-g++"
6-
export CEXT="OFF"
7-
8-
# Then, second a custom-built Linux compiler
9-
elif command -v "riscv64-unknown-linux-gnu-g++" &> /dev/null; then
10-
echo "* Building game scripts with custom GCC/glibc compiler"
11-
GCC_TRIPLE="riscv64-unknown-linux-gnu"
12-
export CXX="ccache $GCC_TRIPLE-g++"
13-
export CEXT="OFF"
14-
151
# System-provided GCC variants
16-
elif command -v "riscv64-linux-gnu-g++-13" &> /dev/null; then
2+
if command -v "riscv64-linux-gnu-g++-13" &> /dev/null; then
173
echo "* Building game scripts with system GCC/glibc compiler"
184
GCC_TRIPLE="riscv64-linux-gnu"
195
export CXX="ccache $GCC_TRIPLE-g++-13"

programs/micro/api/api_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ inline void expect_check(
4343

4444
#define EXPECT(expr) \
4545
api::expect_check( \
46-
[&] \
46+
[&] () -> bool \
4747
{ \
4848
return (expr); \
4949
}, \

0 commit comments

Comments
 (0)