mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-23 07:57:51 -05:00
update broma
This commit is contained in:
parent
26893f1b80
commit
0a584327ff
8 changed files with 33 additions and 232 deletions
|
@ -4,7 +4,7 @@ project(Codegen LANGUAGES C CXX)
|
|||
include(../cmake/CPM.cmake)
|
||||
|
||||
CPMAddPackage("gh:fmtlib/fmt#9.1.0")
|
||||
CPMAddPackage("gh:geode-sdk/Broma#b1adda0")
|
||||
CPMAddPackage("gh:geode-sdk/Broma#a9c1d2e")
|
||||
|
||||
file(GLOB SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "Shared.hpp"
|
||||
#include "TypeOpt.hpp"
|
||||
|
||||
namespace {
|
||||
namespace format_strings {
|
||||
|
@ -76,9 +75,6 @@ Result<tulip::hook::HandlerMetadata> geode::modifier::handlerMetadataForAddress(
|
|||
|
||||
std::string generateAddressHeader(Root& root) {
|
||||
std::string output;
|
||||
|
||||
TypeBank bank;
|
||||
bank.loadFrom(root);
|
||||
output += format_strings::address_begin;
|
||||
|
||||
for (auto& c : root.classes) {
|
||||
|
@ -92,14 +88,12 @@ std::string generateAddressHeader(Root& root) {
|
|||
}
|
||||
|
||||
if (codegen::getStatus(field) == BindStatus::Binded) {
|
||||
auto const ids = bank.getIDs(fn->beginning, c.name);
|
||||
|
||||
address_str = fmt::format(
|
||||
"addresser::get{}Virtual(Resolve<{}>::func(&{}::{}))",
|
||||
str_if("Non", !fn->beginning.is_virtual),
|
||||
codegen::getParameterTypes(fn->beginning),
|
||||
str_if("Non", !fn->prototype.is_virtual),
|
||||
codegen::getParameterTypes(fn->prototype),
|
||||
field.parent,
|
||||
fn->beginning.name
|
||||
fn->prototype.name
|
||||
);
|
||||
}
|
||||
else if (codegen::getStatus(field) == BindStatus::NeedsBinding) {
|
||||
|
|
|
@ -187,7 +187,7 @@ std::string generateBindingHeader(Root& root, ghc::filesystem::path const& singl
|
|||
|
||||
bool unimplementedField = false;
|
||||
for (auto field : cls.fields) {
|
||||
FunctionBegin* fb;
|
||||
MemberFunctionProto* fb;
|
||||
char const* used_format = format_strings::function_definition;
|
||||
|
||||
std::string addressDocs;
|
||||
|
@ -212,11 +212,11 @@ std::string generateBindingHeader(Root& root, ghc::filesystem::path const& singl
|
|||
}
|
||||
continue;
|
||||
} else if (auto fn = field.get_as<OutOfLineField>()) {
|
||||
fb = &fn->beginning;
|
||||
fb = &fn->prototype;
|
||||
addressDocs = " * @note[short] Out of line\n";
|
||||
|
||||
} else if (auto fn = field.get_as<FunctionBindField>()) {
|
||||
fb = &fn->beginning;
|
||||
fb = &fn->prototype;
|
||||
|
||||
if (!codegen::platformNumber(fn->binds)) {
|
||||
used_format = format_strings::error_definition;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "Shared.hpp"
|
||||
#include "TypeOpt.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
@ -58,9 +57,6 @@ namespace geode::modifier {{
|
|||
std::string generateModifyHeader(Root& root, ghc::filesystem::path const& singleFolder) {
|
||||
std::string output;
|
||||
|
||||
TypeBank bank;
|
||||
bank.loadFrom(root);
|
||||
|
||||
for (auto c : root.classes) {
|
||||
if (c.name == "cocos2d") continue;
|
||||
|
||||
|
@ -108,7 +104,6 @@ std::string generateModifyHeader(Root& root, ghc::filesystem::path const& single
|
|||
for (auto& f : c.fields) {
|
||||
if (codegen::getStatus(f) != BindStatus::Unbindable) {
|
||||
auto begin = f.get_fn();
|
||||
auto func = TypeBank::makeFunc(*begin, c.name);
|
||||
|
||||
std::string format_string;
|
||||
|
||||
|
@ -127,11 +122,10 @@ std::string generateModifyHeader(Root& root, ghc::filesystem::path const& single
|
|||
single_output += fmt::format(
|
||||
format_string,
|
||||
fmt::arg("addr_index", f.field_id),
|
||||
fmt::arg("pure_index", bank.getPure(*begin, c.name)),
|
||||
fmt::arg("class_name", c.name),
|
||||
fmt::arg("function_name", begin->name),
|
||||
fmt::arg("function_convention", codegen::getModifyConventionName(f)),
|
||||
fmt::arg("parameter_types", fmt::join(func.parameter_types, ", "))
|
||||
fmt::arg("parameter_types", codegen::getParameterTypes(*begin))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ using std::istreambuf_iterator;
|
|||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
using namespace broma;
|
||||
|
||||
std::string generateAddressHeader(Root& root);
|
||||
std::string generateModifyHeader(Root& root, ghc::filesystem::path const& singleFolder);
|
||||
std::string generateWrapperHeader(Root& root);
|
||||
|
@ -84,15 +86,15 @@ namespace codegen {
|
|||
}
|
||||
|
||||
inline BindStatus getStatusWithPlatform(Platform p, Field const& field) {
|
||||
FunctionBegin const* fb;
|
||||
MemberFunctionProto const* fb;
|
||||
|
||||
if (auto fn = field.get_as<FunctionBindField>()) {
|
||||
if (platformNumberWithPlatform(p, fn->binds)) return BindStatus::NeedsBinding;
|
||||
|
||||
fb = &fn->beginning;
|
||||
fb = &fn->prototype;
|
||||
}
|
||||
else if (auto fn = field.get_as<OutOfLineField>()) {
|
||||
fb = &fn->beginning;
|
||||
fb = &fn->prototype;
|
||||
}
|
||||
else return BindStatus::Unbindable;
|
||||
|
||||
|
@ -122,7 +124,7 @@ namespace codegen {
|
|||
return getStatusWithPlatform(codegen::platform, field);
|
||||
}
|
||||
|
||||
inline std::string getParameters(FunctionBegin const& f) { // int p0, float p1
|
||||
inline std::string getParameters(FunctionProto const& f) { // int p0, float p1
|
||||
std::vector<std::string> parameters;
|
||||
|
||||
for (auto& [t, n] : f.args) {
|
||||
|
@ -132,7 +134,7 @@ namespace codegen {
|
|||
return fmt::format("{}", fmt::join(parameters, ", "));
|
||||
}
|
||||
|
||||
inline std::string getParameterTypes(FunctionBegin const& f) { // int, float
|
||||
inline std::string getParameterTypes(FunctionProto const& f) { // int, float
|
||||
std::vector<std::string> parameters;
|
||||
|
||||
for (auto& [t, n] : f.args) {
|
||||
|
@ -142,7 +144,7 @@ namespace codegen {
|
|||
return fmt::format("{}", fmt::join(parameters, ", "));
|
||||
}
|
||||
|
||||
inline std::string getParameterNames(FunctionBegin const& f) { // p0, p1
|
||||
inline std::string getParameterNames(FunctionProto const& f) { // p0, p1
|
||||
std::vector<std::string> parameters;
|
||||
|
||||
for (auto& [t, n] : f.args) {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "Shared.hpp"
|
||||
#include "TypeOpt.hpp"
|
||||
|
||||
namespace { namespace format_strings {
|
||||
char const* source_start = R"CAC(
|
||||
|
@ -118,9 +117,6 @@ auto {class_name}::{function_name}({parameters}){const} -> decltype({function_na
|
|||
std::string generateBindingSource(Root& root) {
|
||||
std::string output(format_strings::source_start);
|
||||
|
||||
TypeBank bank;
|
||||
bank.loadFrom(root);
|
||||
|
||||
for (auto& c : root.classes) {
|
||||
|
||||
for (auto& f : c.fields) {
|
||||
|
@ -138,25 +134,25 @@ std::string generateBindingSource(Root& root) {
|
|||
continue;
|
||||
}
|
||||
|
||||
switch (fn->beginning.type) {
|
||||
switch (fn->prototype.type) {
|
||||
case FunctionType::Ctor:
|
||||
case FunctionType::Dtor:
|
||||
output += fmt::format(format_strings::ool_structor_function_definition,
|
||||
fmt::arg("function_name", fn->beginning.name),
|
||||
fmt::arg("const", str_if(" const ", fn->beginning.is_const)),
|
||||
fmt::arg("function_name", fn->prototype.name),
|
||||
fmt::arg("const", str_if(" const ", fn->prototype.is_const)),
|
||||
fmt::arg("class_name", c.name),
|
||||
fmt::arg("parameters", codegen::getParameters(fn->beginning)),
|
||||
fmt::arg("parameters", codegen::getParameters(fn->prototype)),
|
||||
fmt::arg("definition", fn->inner)
|
||||
);
|
||||
break;
|
||||
default:
|
||||
output += fmt::format(format_strings::ool_function_definition,
|
||||
fmt::arg("function_name", fn->beginning.name),
|
||||
fmt::arg("const", str_if(" const ", fn->beginning.is_const)),
|
||||
fmt::arg("function_name", fn->prototype.name),
|
||||
fmt::arg("const", str_if(" const ", fn->prototype.is_const)),
|
||||
fmt::arg("class_name", c.name),
|
||||
fmt::arg("parameters", codegen::getParameters(fn->beginning)),
|
||||
fmt::arg("parameters", codegen::getParameters(fn->prototype)),
|
||||
fmt::arg("definition", fn->inner),
|
||||
fmt::arg("return", fn->beginning.ret.name)
|
||||
fmt::arg("return", fn->prototype.ret.name)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
@ -172,7 +168,7 @@ std::string generateBindingSource(Root& root) {
|
|||
|
||||
char const* used_declare_format;
|
||||
|
||||
switch (fn->beginning.type) {
|
||||
switch (fn->prototype.type) {
|
||||
case FunctionType::Normal:
|
||||
used_declare_format = format_strings::declare_member;
|
||||
break;
|
||||
|
@ -184,27 +180,22 @@ std::string generateBindingSource(Root& root) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (fn->beginning.is_static)
|
||||
if (fn->prototype.is_static)
|
||||
used_declare_format = format_strings::declare_static;
|
||||
if (fn->beginning.is_virtual && fn->beginning.type != FunctionType::Dtor)
|
||||
if (fn->prototype.is_virtual && fn->prototype.type != FunctionType::Dtor)
|
||||
used_declare_format = format_strings::declare_virtual;
|
||||
|
||||
auto ids = bank.getIDs(fn->beginning, c.name);
|
||||
|
||||
output += fmt::format(used_declare_format,
|
||||
fmt::arg("class_name", c.name),
|
||||
fmt::arg("unqualified_class_name", codegen::getUnqualifiedClassName(c.name)),
|
||||
fmt::arg("const", str_if(" const ", fn->beginning.is_const)),
|
||||
fmt::arg("const", str_if(" const ", fn->prototype.is_const)),
|
||||
fmt::arg("convention", codegen::getModifyConventionName(f)),
|
||||
fmt::arg("function_name", fn->beginning.name),
|
||||
fmt::arg("meta_index", ids.meta),
|
||||
fmt::arg("member_index", ids.member),
|
||||
fmt::arg("ret_index", ids.ret),
|
||||
fmt::arg("function_name", fn->prototype.name),
|
||||
fmt::arg("addr_index", f.field_id),
|
||||
fmt::arg("parameters", codegen::getParameters(fn->beginning)),
|
||||
fmt::arg("parameter_types", codegen::getParameterTypes(fn->beginning)),
|
||||
fmt::arg("arguments", codegen::getParameterNames(fn->beginning)),
|
||||
fmt::arg("parameter_comma", str_if(", ", !fn->beginning.args.empty()))
|
||||
fmt::arg("parameters", codegen::getParameters(fn->prototype)),
|
||||
fmt::arg("parameter_types", codegen::getParameterTypes(fn->prototype)),
|
||||
fmt::arg("arguments", codegen::getParameterNames(fn->prototype)),
|
||||
fmt::arg("parameter_comma", str_if(", ", !fn->prototype.args.empty()))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,180 +0,0 @@
|
|||
#include "Shared.hpp"
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
namespace {
|
||||
enum class FuncType : int {
|
||||
Structor,
|
||||
Static,
|
||||
Member
|
||||
};
|
||||
struct Func {
|
||||
std::string return_type;
|
||||
bool is_const;
|
||||
std::string class_name;
|
||||
std::vector<std::string> parameter_types;
|
||||
FuncType type;
|
||||
|
||||
std::string toStr() const {
|
||||
return fmt::format("{}{}{}{}{}",
|
||||
return_type,
|
||||
class_name,
|
||||
fmt::join(parameter_types, ","),
|
||||
is_const ? " const " : "",
|
||||
static_cast<int>(type)
|
||||
);
|
||||
}
|
||||
|
||||
bool operator<(Func const& f) const {
|
||||
return toStr() < f.toStr();
|
||||
}
|
||||
|
||||
bool operator==(Func const& f) const {
|
||||
return (
|
||||
return_type == f.return_type &&
|
||||
is_const == f.is_const &&
|
||||
class_name == f.class_name &&
|
||||
parameter_types == f.parameter_types &&
|
||||
type == f.type
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct Ids {
|
||||
int ret = -1;
|
||||
int func = -1;
|
||||
int pure = -1;
|
||||
int meta = -1;
|
||||
int member = -1;
|
||||
};
|
||||
|
||||
class TypeBank {
|
||||
std::vector<Func> m_stuff;
|
||||
public:
|
||||
static std::string getReturn(FunctionBegin const& fn, std::string const& parent) {
|
||||
if (fn.type != FunctionType::Normal)
|
||||
return "void";
|
||||
|
||||
if (fn.ret.name == "auto") {
|
||||
std::vector<std::string> declvals;
|
||||
|
||||
for (auto& [t, n] : fn.args) {
|
||||
declvals.push_back(fmt::format("std::declval<{}>()", t.name));
|
||||
}
|
||||
|
||||
return fmt::format(
|
||||
fn.is_static ? "decltype({}::{}({}))" : "decltype(std::declval<{}>().{}({}))",
|
||||
parent,
|
||||
fn.name,
|
||||
fmt::join(declvals, ", ")
|
||||
);
|
||||
}
|
||||
|
||||
return fn.ret.name;
|
||||
}
|
||||
|
||||
static Func makeFunc(FunctionBegin const& fn, std::string const& parent) {
|
||||
Func f;
|
||||
f.return_type = TypeBank::getReturn(fn, parent);
|
||||
f.is_const = fn.is_const;
|
||||
f.class_name = parent;
|
||||
|
||||
for (auto& arg : fn.args) {
|
||||
f.parameter_types.push_back(arg.first.name);
|
||||
}
|
||||
|
||||
if (fn.is_static)
|
||||
f.type = FuncType::Static;
|
||||
else if (fn.type != FunctionType::Normal)
|
||||
f.type = FuncType::Structor;
|
||||
else
|
||||
f.type = FuncType::Member;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
void loadFrom(Root& root) {
|
||||
for (auto& c : root.classes) {
|
||||
for (auto& f : c.fields) {
|
||||
if (codegen::getStatus(f) == BindStatus::Unbindable)
|
||||
continue;
|
||||
|
||||
m_stuff.push_back(TypeBank::makeFunc(*f.get_fn(), c.name));
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(m_stuff.begin(), m_stuff.end());
|
||||
m_stuff.erase(std::unique(m_stuff.begin(), m_stuff.end()), m_stuff.end());
|
||||
}
|
||||
|
||||
std::vector<Func> const& typeList() { return m_stuff; }
|
||||
|
||||
Ids getIDs(FunctionBegin const& fn, std::string const& parent) {
|
||||
Ids out;
|
||||
Func in_f = TypeBank::makeFunc(fn, parent);
|
||||
|
||||
int i = 0;
|
||||
for (auto f : m_stuff) {
|
||||
if (out.ret == -1 && f.return_type == in_f.return_type) {
|
||||
out.ret = i;
|
||||
}
|
||||
|
||||
if (out.func == -1) {
|
||||
if (in_f.type == FuncType::Member) {
|
||||
if (f == in_f) out.func = i;
|
||||
} else if (in_f.type == FuncType::Structor) {
|
||||
if (
|
||||
f.return_type == in_f.return_type &&
|
||||
f.class_name == in_f.class_name &&
|
||||
f.is_const == in_f.is_const &&
|
||||
f.parameter_types == in_f.parameter_types
|
||||
) out.func = i;
|
||||
} else {
|
||||
if (
|
||||
f.return_type == in_f.return_type &&
|
||||
f.parameter_types == in_f.parameter_types &&
|
||||
f.type == in_f.type
|
||||
) out.func = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (out.meta == -1 || out.member == -1) {
|
||||
Func assume_member = f;
|
||||
assume_member.type = FuncType::Member;
|
||||
|
||||
if (in_f == assume_member) {
|
||||
out.meta = i;
|
||||
} else if (out.func != -1) {
|
||||
out.meta = out.func;
|
||||
}
|
||||
}
|
||||
|
||||
if (out.pure == -1 && f.return_type == in_f.return_type && f.parameter_types == in_f.parameter_types) {
|
||||
out.pure = i;
|
||||
}
|
||||
|
||||
if (out.ret != -1 && out.func != -1 && out.pure != -1)
|
||||
break;
|
||||
++i;
|
||||
}
|
||||
|
||||
out.member = out.func;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
int getPure(FunctionBegin const& fn, std::string const& parent) {
|
||||
Func in_f = TypeBank::makeFunc(fn, parent);
|
||||
|
||||
int i = 0;
|
||||
for (auto f : m_stuff) {
|
||||
if (f.return_type == in_f.return_type && f.parameter_types == in_f.parameter_types) {
|
||||
return i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue