mirror of
https://github.com/open-goal/jak-project
synced 2026-08-19 22:12:24 -04:00
[TypeSystem] add heap-base property to types (#431)
* support heap base in the type system * lock around modification of status
This commit is contained in:
+18
-11
@@ -103,8 +103,11 @@ bool Field::operator==(const Field& other) const {
|
||||
|
||||
// parent class of types, also has method logic.
|
||||
|
||||
Type::Type(std::string parent, std::string name, bool is_boxed)
|
||||
: m_parent(std::move(parent)), m_name(std::move(name)), m_is_boxed(is_boxed) {
|
||||
Type::Type(std::string parent, std::string name, bool is_boxed, int heap_base)
|
||||
: m_parent(std::move(parent)),
|
||||
m_name(std::move(name)),
|
||||
m_is_boxed(is_boxed),
|
||||
m_heap_base(heap_base) {
|
||||
m_runtime_name = m_name;
|
||||
}
|
||||
|
||||
@@ -143,7 +146,8 @@ std::string Type::get_parent() const {
|
||||
bool Type::is_equal(const Type& other) const {
|
||||
return m_parent == other.m_parent && m_name == other.m_name && m_is_boxed == other.m_is_boxed &&
|
||||
m_methods == other.m_methods && m_new_method_info == other.m_new_method_info &&
|
||||
m_new_method_info_defined == other.m_new_method_info_defined;
|
||||
m_new_method_info_defined == other.m_new_method_info_defined &&
|
||||
m_heap_base == other.m_heap_base;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -253,7 +257,7 @@ std::string Type::print_method_info() const {
|
||||
// Special Type for both "none" and "_type_" types
|
||||
// it's an error to try to do anything with Null.
|
||||
|
||||
NullType::NullType(std::string name) : Type("", std::move(name), false) {}
|
||||
NullType::NullType(std::string name) : Type("", std::move(name), false, 0) {}
|
||||
|
||||
bool NullType::is_reference() const {
|
||||
throw std::runtime_error("is_reference called on NullType");
|
||||
@@ -314,7 +318,7 @@ ValueType::ValueType(std::string parent,
|
||||
int size,
|
||||
bool sign_extend,
|
||||
RegClass reg)
|
||||
: Type(std::move(parent), std::move(name), is_boxed),
|
||||
: Type(std::move(parent), std::move(name), is_boxed, 0),
|
||||
m_size(size),
|
||||
m_sign_extend(sign_extend),
|
||||
m_reg_kind(reg) {}
|
||||
@@ -431,8 +435,8 @@ bool ValueType::operator==(const Type& other) const {
|
||||
// This means this type behaves like a C pointer - the thing that's passed around is a reference
|
||||
// to some memory somewhere.
|
||||
|
||||
ReferenceType::ReferenceType(std::string parent, std::string name, bool is_boxed)
|
||||
: Type(std::move(parent), std::move(name), is_boxed) {}
|
||||
ReferenceType::ReferenceType(std::string parent, std::string name, bool is_boxed, int heap_base)
|
||||
: Type(std::move(parent), std::move(name), is_boxed, heap_base) {}
|
||||
|
||||
/*!
|
||||
* By definition, this is a reference!
|
||||
@@ -478,8 +482,11 @@ StructureType::StructureType(std::string parent,
|
||||
std::string name,
|
||||
bool boxed,
|
||||
bool dynamic,
|
||||
bool pack)
|
||||
: ReferenceType(std::move(parent), std::move(name), boxed), m_dynamic(dynamic), m_pack(pack) {}
|
||||
bool pack,
|
||||
int heap_base)
|
||||
: ReferenceType(std::move(parent), std::move(name), boxed, heap_base),
|
||||
m_dynamic(dynamic),
|
||||
m_pack(pack) {}
|
||||
|
||||
std::string StructureType::print() const {
|
||||
std::string result = fmt::format(
|
||||
@@ -588,8 +595,8 @@ bool StructureType::lookup_field(const std::string& name, Field* out) {
|
||||
// BasicType
|
||||
/////////////////
|
||||
|
||||
BasicType::BasicType(std::string parent, std::string name, bool dynamic)
|
||||
: StructureType(std::move(parent), std::move(name), true, dynamic) {}
|
||||
BasicType::BasicType(std::string parent, std::string name, bool dynamic, int heap_base)
|
||||
: StructureType(std::move(parent), std::move(name), true, dynamic, false, heap_base) {}
|
||||
|
||||
std::string BasicType::print() const {
|
||||
std::string result =
|
||||
|
||||
@@ -93,8 +93,10 @@ class Type {
|
||||
|
||||
bool is_boxed() const { return m_is_boxed; }
|
||||
|
||||
int heap_base() const { return m_heap_base; }
|
||||
|
||||
protected:
|
||||
Type(std::string parent, std::string name, bool is_boxed);
|
||||
Type(std::string parent, std::string name, bool is_boxed, int heap_base);
|
||||
|
||||
std::vector<MethodInfo> m_methods;
|
||||
MethodInfo m_new_method_info;
|
||||
@@ -105,6 +107,8 @@ class Type {
|
||||
bool m_allow_in_runtime = true;
|
||||
std::string m_runtime_name;
|
||||
bool m_is_boxed = false; // does this have runtime type information?
|
||||
|
||||
int m_heap_base = 0;
|
||||
};
|
||||
|
||||
/*!
|
||||
@@ -170,7 +174,7 @@ class ValueType : public Type {
|
||||
*/
|
||||
class ReferenceType : public Type {
|
||||
public:
|
||||
ReferenceType(std::string parent, std::string name, bool is_boxed);
|
||||
ReferenceType(std::string parent, std::string name, bool is_boxed, int heap_base);
|
||||
bool is_reference() const override;
|
||||
int get_load_size() const override;
|
||||
bool get_load_signed() const override;
|
||||
@@ -232,9 +236,10 @@ class StructureType : public ReferenceType {
|
||||
public:
|
||||
StructureType(std::string parent,
|
||||
std::string name,
|
||||
bool boxed = false,
|
||||
bool dynamic = false,
|
||||
bool pack = false);
|
||||
bool boxed,
|
||||
bool dynamic,
|
||||
bool pack,
|
||||
int heap_base);
|
||||
std::string print() const override;
|
||||
void inherit(StructureType* parent);
|
||||
const std::vector<Field>& fields() const { return m_fields; }
|
||||
@@ -248,6 +253,7 @@ class StructureType : public ReferenceType {
|
||||
bool is_dynamic() const { return m_dynamic; }
|
||||
~StructureType() = default;
|
||||
void set_pack(bool pack) { m_pack = pack; }
|
||||
void set_heap_base(int hb) { m_heap_base = hb; }
|
||||
bool is_packed() const { return m_pack; }
|
||||
bool is_allowed_misalign() const { return m_allow_misalign; };
|
||||
void set_allow_misalign(bool misalign) { m_allow_misalign = misalign; }
|
||||
@@ -276,7 +282,7 @@ class StructureType : public ReferenceType {
|
||||
|
||||
class BasicType : public StructureType {
|
||||
public:
|
||||
BasicType(std::string parent, std::string name, bool dynamic = false);
|
||||
BasicType(std::string parent, std::string name, bool dynamic, int heap_base);
|
||||
int get_offset() const override;
|
||||
int get_inline_array_start_alignment() const override;
|
||||
std::string print() const override;
|
||||
|
||||
@@ -1009,7 +1009,7 @@ int TypeSystem::get_size_in_type(const Field& field) const {
|
||||
StructureType* TypeSystem::add_builtin_structure(const std::string& parent,
|
||||
const std::string& type_name,
|
||||
bool boxed) {
|
||||
add_type(type_name, std::make_unique<StructureType>(parent, type_name, boxed));
|
||||
add_type(type_name, std::make_unique<StructureType>(parent, type_name, boxed, false, false, 0));
|
||||
return get_type_of_type<StructureType>(type_name);
|
||||
}
|
||||
|
||||
@@ -1018,7 +1018,7 @@ StructureType* TypeSystem::add_builtin_structure(const std::string& parent,
|
||||
* things in the wrong order.
|
||||
*/
|
||||
BasicType* TypeSystem::add_builtin_basic(const std::string& parent, const std::string& type_name) {
|
||||
add_type(type_name, std::make_unique<BasicType>(parent, type_name));
|
||||
add_type(type_name, std::make_unique<BasicType>(parent, type_name, false, 0));
|
||||
return get_type_of_type<BasicType>(type_name);
|
||||
}
|
||||
|
||||
@@ -1339,11 +1339,15 @@ std::string TypeSystem::generate_deftype_footer(const Type* type) const {
|
||||
}
|
||||
}
|
||||
|
||||
if (type->heap_base()) {
|
||||
result.append(fmt::format(" :heap-base #x{:x}\n", type->heap_base()));
|
||||
}
|
||||
|
||||
auto method_count = get_next_method_id(type);
|
||||
result.append(fmt::format(" :method-count-assert {}\n", get_next_method_id(type)));
|
||||
result.append(fmt::format(" :size-assert #x{:x}\n", type->get_size_in_memory()));
|
||||
TypeFlags flags;
|
||||
flags.heap_base = 0;
|
||||
flags.heap_base = type->heap_base();
|
||||
flags.size = type->get_size_in_memory();
|
||||
flags.pad = 0;
|
||||
flags.methods = method_count;
|
||||
|
||||
@@ -433,7 +433,7 @@ DeftypeResult parse_deftype(const goos::Object& deftype, TypeSystem* ts) {
|
||||
DeftypeResult result;
|
||||
|
||||
if (is_type("basic", parent_type, ts)) {
|
||||
auto new_type = std::make_unique<BasicType>(parent_type_name, name);
|
||||
auto new_type = std::make_unique<BasicType>(parent_type_name, name, false, 0);
|
||||
auto pto = dynamic_cast<BasicType*>(ts->lookup_type(parent_type));
|
||||
assert(pto);
|
||||
new_type->inherit(pto);
|
||||
@@ -451,9 +451,10 @@ DeftypeResult parse_deftype(const goos::Object& deftype, TypeSystem* ts) {
|
||||
name);
|
||||
throw std::runtime_error("invalid pack option on basic");
|
||||
}
|
||||
new_type->set_heap_base(result.flags.heap_base);
|
||||
ts->add_type(name, std::move(new_type));
|
||||
} else if (is_type("structure", parent_type, ts)) {
|
||||
auto new_type = std::make_unique<StructureType>(parent_type_name, name);
|
||||
auto new_type = std::make_unique<StructureType>(parent_type_name, name, false, false, false, 0);
|
||||
auto pto = dynamic_cast<StructureType*>(ts->lookup_type(parent_type));
|
||||
assert(pto);
|
||||
new_type->inherit(pto);
|
||||
@@ -467,6 +468,7 @@ DeftypeResult parse_deftype(const goos::Object& deftype, TypeSystem* ts) {
|
||||
if (sr.allow_misaligned) {
|
||||
new_type->set_allow_misalign(true);
|
||||
}
|
||||
new_type->set_heap_base(result.flags.heap_base);
|
||||
ts->add_type(name, std::move(new_type));
|
||||
} else if (is_type("integer", parent_type, ts)) {
|
||||
auto pto = ts->lookup_type(parent_type);
|
||||
|
||||
Reference in New Issue
Block a user