Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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