update broma

This commit is contained in:
altalk23 2023-08-15 12:46:49 +03:00
parent 26893f1b80
commit 0a584327ff
8 changed files with 33 additions and 232 deletions

View file

@ -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

View file

@ -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) {

View file

@ -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;

View file

@ -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))
);
}
}

View file

@ -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) {

View file

@ -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()))
);
}
}

View file

@ -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;
}
};
}