This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class StructureType : public Type { | |
public: | |
StructureType(std::string name, std::vector<Type*> fields) | |
: name(std::move(name)) | |
, fields(std::move(fields)) | |
, typeInfo(this->name.c_str(), static_cast<abi::__class_type_info const*>(&typeid(Value))) { | |
vtable.offsetToTop = 0; | |
vtable.typeInfo = &typeInfo; | |
vtable.dtor1 = dtor; | |
vtable.dtor2 = dtor; | |
} | |
boost::intrusive_ptr<Value> make() const { | |
// First, initialize the value with the constructor of Value. | |
// Value is abstract so we need to make a concrete subclass. | |
class ConcreteValue : public Value { }; | |
auto memory = operator new(size()); | |
new (memory) ConcreteValue(); | |
// Next, patch the vptr of the object. This is a massive hack which | |
// saves us a lot of work because we can nicely integrate with the | |
// C++ type system at runtime. | |
auto vptr = &vtable.dtor1; | |
std::memcpy(memory, &vptr, sizeof(void*)); | |
return static_cast<Value*>(memory); | |
} | |
std::size_t size() const { | |
auto padding = alignof(Value*) % sizeof(Value); | |
return sizeof(Value) + padding + fields.size() * sizeof(Value*); | |
} | |
private: | |
static void dtor(void* vself) { | |
auto self = static_cast<Value*>(vself); | |
// TODO: destroy all fields. | |
self->Value::~Value(); | |
} | |
std::string name; | |
std::vector<Type*> fields; | |
abi::__si_class_type_info typeInfo; | |
struct { | |
std::ptrdiff_t offsetToTop; | |
std::type_info const* typeInfo; | |
void (* dtor1)(void*); | |
void (* dtor2)(void*); | |
} vtable; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment