Skip to content

Commit

Permalink
Add MinGW build and improve Callable support
Browse files Browse the repository at this point in the history
  • Loading branch information
fwsGonzo committed Jul 20, 2024
1 parent 3ab806b commit 416cb8f
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 19 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
build/
.build/
.mingw/
.vscode/
program/test
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.9.4)
project(riscv CXX)

option(SANITIZE "Enable sanitizers" OFF)
option(STATIC_BUILD "Build statically" OFF)

set(SOURCES
src/gvar.cpp
Expand All @@ -11,6 +12,9 @@ set(SOURCES
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")

# Check if MinGW
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20")

if (SANITIZE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address,undefined")
endif()
Expand All @@ -29,3 +33,7 @@ target_compile_definitions(riscv PUBLIC

add_library(godot-riscv SHARED ${SOURCES})
target_link_libraries(godot-riscv PUBLIC riscv godot-cpp)

if (STATIC_BUILD)
target_link_libraries(godot-riscv PUBLIC -static)
endif()
2 changes: 1 addition & 1 deletion libriscv
8 changes: 8 additions & 0 deletions mingw.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -e

mkdir -p .mingw
pushd .mingw
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=mingw_toolchain.cmake -DSTATIC_BUILD=ON
make -j6
popd
14 changes: 14 additions & 0 deletions mingw_toolchain.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(THREADS_PREFER_PTHREAD_FLAG ON)

set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)
set(MINGW_TOOLCHAIN ON)

set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc-posix)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++-posix)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)

set(CMAKE_FIND_ROOT_PATH
/usr/${TOOLCHAIN_PREFIX}
)
15 changes: 14 additions & 1 deletion program/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ int main()
}

extern "C"
void my_function()
void my_function(std::span<Variant> args)
{
UtilityFunctions::print("Hello, ", 124.5, " world!\n");
}
Expand All @@ -60,3 +60,16 @@ void function3(std::span<Variant> args)
UtilityFunctions::print("x = ", args[0], " y = ", args[1], " text = ", args[2]);
//UtilityFunctions::print("x = ", args[0], " y = ", args[1]);
}

extern "C"
void final_function(std::span<Variant> args)
{
UtilityFunctions::print("The function was called!!\n");
}
extern "C"
void trampoline_function(std::span<Variant> args)
{
UtilityFunctions::print("Trampoline is calling first argument...\n");
args[0].call("Hello World!");
UtilityFunctions::print("First argument called!\n");
}
8 changes: 4 additions & 4 deletions program/variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

#include "syscalls.h"

MAKE_SYSCALL(ECALL_VCALL, void, sys_pcall, Variant*, const char*, size_t, const Variant**, size_t, Variant&);
MAKE_SYSCALL(ECALL_VCALL, void, sys_vcall, Variant*, const char*, size_t, const Variant*, size_t, Variant&);
MAKE_SYSCALL(ECALL_VEVAL, bool, sys_veval, int, const Variant*, const Variant*, Variant*);

void Variant::callp(const std::string &method, const Variant **args, int argcount, Variant &r_ret, int &r_error)
void Variant::callp(const std::string &method, const Variant *args, int argcount, Variant &r_ret, int &r_error)
{
if (m_type != OBJECT) {
if (m_type != OBJECT && m_type != CALLABLE) {
r_error = 1;
return;
}

sys_pcall(this, method.c_str(), method.size(), args, argcount, r_ret);
sys_vcall(this, method.c_str(), method.size(), args, argcount, r_ret);
}

void Variant::evaluate(const Operator &op, const Variant &a, const Variant &b, Variant &r_ret, bool &r_valid)
Expand Down
41 changes: 34 additions & 7 deletions program/variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ struct Variant
};

Variant() = default;
Variant(const Variant &other);
Variant(Variant &&other);
~Variant();

// Constructor for integers and floats
Expand Down Expand Up @@ -141,18 +143,23 @@ struct Variant
operator float() const;
operator std::string() const;

void callp(const std::string &method, const Variant **args, int argcount, Variant &r_ret, int &r_error);
void callp(const std::string &method, const Variant *args, int argcount, Variant &r_ret, int &r_error);

template <typename... Args>
Variant call(const std::string &method, Args... args) {
Variant method_call(const std::string &method, Args... args) {
std::array<Variant, sizeof...(args)> vargs = { args... };
Variant result;
int error;
callp(method, vargs.data(), vargs.size(), result, error);
return result;
}

template <typename... Args>
Variant call(Args... args) {
std::array<Variant, sizeof...(args)> vargs = { args... };
std::array<const Variant *, sizeof...(args)> argptrs;
for (size_t i = 0; i < vargs.size(); i++) {
argptrs[i] = &vargs[i];
}
Variant result;
int error;
callp(method, argptrs.data(), argptrs.size(), result, error);
callp("call", vargs.data(), vargs.size(), result, error);
return result;
}

Expand All @@ -167,8 +174,10 @@ struct Variant
Type get_type() const noexcept { return m_type; }

private:
static constexpr unsigned GODOT_VARIANT_SIZE = 24;
Type m_type = NIL;
union {
uint8_t opaque[GODOT_VARIANT_SIZE] { 0 };
bool b;
int64_t i;
double f;
Expand Down Expand Up @@ -260,6 +269,24 @@ inline Variant::operator std::string() const
throw std::bad_cast();
}

inline Variant::Variant(const Variant &other)
{
m_type = other.m_type;
if (m_type == STRING)
v.s = new std::string(*other.v.s);
else
v = other.v;
}
inline Variant::Variant(Variant &&other)
{
m_type = other.m_type;
if (m_type == STRING)
v.s = other.v.s;
else
v = other.v;

other.m_type = NIL;
}
inline Variant::~Variant()
{
if (m_type == STRING)
Expand Down
12 changes: 12 additions & 0 deletions src/gvar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ Variant GuestVariant::toVariant(const machine_t& machine) const
auto s = machine.memory.rvspan<GuestStdString>(v.s, 1);
return s[0].to_godot_string(machine);
}
case Variant::CALLABLE: {
// XXX: Here we obviously need to verify that the variant
// is exactly as passed into the VM, and not something else.
printf("GuestVariant::toVariant(): CALLABLE\n");
Variant* hostv = (Variant*)v.opaque;
return *hostv;
}
default:
UtilityFunctions::print("GuestVariant::toVariant(): Unsupported type: ", type);
return Variant();
Expand Down Expand Up @@ -49,6 +56,11 @@ void GuestVariant::set(machine_t& machine, const Variant& value)
this->v.s = ptr;
break;
}
case Variant::CALLABLE: {
this->type = Variant::CALLABLE;
std::memcpy(this->v.opaque, &value, sizeof(GuestVariant::GODOT_VARIANT_SIZE));
break;
}
default:
UtilityFunctions::print("SetVariant(): Unsupported type: ", value.get_type());
break;
Expand Down
2 changes: 2 additions & 0 deletions src/riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,13 @@ struct GuestVariant {
Variant toVariant(const machine_t& machine) const;
void set(machine_t& machine, const Variant& value);

static constexpr unsigned GODOT_VARIANT_SIZE = 24;
Variant::Type type;
union {
bool b;
int64_t i;
double f;
gaddr_t s;
uint8_t opaque[GODOT_VARIANT_SIZE];
} v;
};
14 changes: 8 additions & 6 deletions src/syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ namespace riscv

APICALL(api_vcall)
{
auto [vp, method, args, vret] = machine.sysargs<GuestVariant*, GuestStdString, std::span<GuestVariant>, GuestVariant*>();
auto [vp, method, mlen, args, vret] = machine.sysargs<GuestVariant*, std::string, unsigned, std::span<GuestVariant>, GuestVariant*>();
(void)mlen;

auto& emu = riscv::emu(machine);

emu.print("Calling method: " + method.to_string(machine));
emu.print("Calling method: " + std::string(method));

std::array<Variant, 64> vargs;
std::array<const Variant*, 64> argptrs;
Expand All @@ -38,20 +39,21 @@ namespace riscv
emu.print("Too many arguments.");
return;
}
printf("args.size() = %zu\n", args.size());

for (size_t i = 0; i < args.size(); i++)
{
printf("args[%zu] = %p\n", i, &args[i]);
vargs[i] = args[i].toVariant(machine);
argptrs[i] = &vargs[i];
}

auto vcall = vp->toVariant(machine);
Variant ret;
GDExtensionCallError error;
vcall.callp(method.to_godot_string(machine), argptrs.data(), args.size(), ret, error);
vcall.callp(method.c_str(), argptrs.data(), args.size(), ret, error);

// XXX: Set vret to ret.
//*vret = GuestVariant::fromVariant(machine, ret);
vret->set(machine, ret);
}

APICALL(api_veval)
Expand All @@ -67,7 +69,7 @@ namespace riscv
Variant::evaluate(static_cast<Variant::Operator>(op), ap->toVariant(machine), bp->toVariant(machine), ret, valid);

machine.set_result(valid);
// XXX: Set retp to ret.
retp->set(machine, ret);
}

}
Expand Down

0 comments on commit 416cb8f

Please sign in to comment.