Commit deb3fc4d authored by zygzagZ's avatar zygzagZ

Generation of virt tables

parent 956f197d
......@@ -2894,7 +2894,7 @@ if (!type_) return "function";
bool Fun::isEqual(Type const *other, bool sub) const {
if (const Fun* casted = dynamic_cast<const Fun*>(other)) {
if (!type_->isEqual(casted->type_, sub) || listtype_->size() != casted->listtype_->size()) {
if (!casted->type_->isEqual(type_, sub) || listtype_->size() != casted->listtype_->size()) {
return false;
}
for (unsigned int i = 0; i < listtype_->size(); i++) {
......@@ -2920,3 +2920,7 @@ bool ClassT::isEqual(Type const *other, bool sub) const {
}
return false;
}
ClassInfoPtr ClassT::getClass() const {
return dynamic_pointer_cast<ClassInfo>(pident_->var.lock());
}
\ No newline at end of file
......@@ -237,6 +237,7 @@ public:
bool operator==(Type const & f) const { return isEqual(&f); }
bool operator!=(Type const & f) const { return !isEqual(&f); }
virtual size_t size() const = 0;
ClassInfoPtr getClass() const { return nullptr; };
};
class Expr : public Visitable
......@@ -759,6 +760,7 @@ public:
std::string printName() const { return pident_ ? ("class " + pident_->string_) : "class"; }
bool isEqual(Type const *other, bool sub = false) const;
size_t size() const override { return 4; };
ClassInfoPtr getClass() const;
};
class Fun : public Type
......
......@@ -44,11 +44,19 @@ string Compiler::compile(Visitable *v) {
compileFunction(f);
}
for (const auto& c : scope->classes) {
for (const auto& f : c->functions) {
compileFunction(f);
}
}
for (const auto& it : quadGen.getStrings()) {
buf << "_str_" << it.second << ":\n"
<< ".string " << std::quoted(it.first) << "\n";
}
genVirtTables();
return buf.str();
}
......@@ -172,6 +180,31 @@ void Compiler::printFunction(const QuadrupleGenerator::Result& quadEnv, const Fu
}
}
void Compiler::genVirtTables() {
for (const auto &c : scope->classes) {
if (!c->functionCount) continue;
buf << quoted(getVirtName(c)) << ":\n";
vector<string> names(c->functionCount, "");
auto p = c;
while (p) {
for (auto &f : p->functions) {
assert(f->offset < names.size());
string &s = names[f->offset];
if (s.empty()) {
s = mangleFunctionName(f);
}
}
p = p->getClassParent();
}
for (auto &s : names) {
if (s.empty())
buf << "\t.long 0\n";
else
buf << "\t.long " << quoted(s) << endl;
}
}
}
const char* const Register::names[9] = {"eax", "ebx", "ecx", "edx", "edi", "esi", "ebp", "esp", "eip"};
const vector<Register> Register::all = {0, 1, 2, 3, 4, 5, 6, 7, 8};
const vector<Register> Register::callerSaved = {2, 3};
......@@ -208,8 +241,34 @@ string Compiler::getRef(const VariablePtr &v) {
}
void Compiler::generateQAlloc(QAlloc &q) {
// memory = extension
throw runtime_error("Memory alloc unimplemented!");
if (!q.aliveAfter.count(q.loc)) { return; }
// int len, size_t size, void* virtTab
auto saveRegs = registersToSave(q);
for (auto r : saveRegs) {
if (r != Register(q.loc))
append("PUSHL", r);
}
if (q.virtSymbol.empty()) {
append("PUSHL", "$0");
} else {
append("PUSHL", "$" + quote(q.virtSymbol));
}
if (q.count) {
append("PUSHL", getRef(q.count));
}
append("PUSHL", "$" + to_string(q.size));
append("CALL", q.count ? "__latte_mem_init_array" : "__latte_mem_init");
append("ADDL", "$" + to_string(q.count ? 12 : 8), "%esp");
for (auto r = saveRegs.rbegin(); r != saveRegs.rend(); r++) {
if (*r != Register(q.loc)) {
append("POPL", *r);
}
}
append("MOVL", "%eax", getRef(q.loc));
}
void Compiler::generateQWrite(QWrite &q) {
......
......@@ -88,6 +88,7 @@ private:
void compileFunction(const FunctionInfoPtr& f);
void printFunction(const QuadrupleGenerator::Result& quadEnv, const FunctionInfoPtr& f);
void genVirtTables();
string getRef(const VariablePtr &v);
void generatePhiXCHG(const map<VariablePtr, VariablePtr> &varMap);
......@@ -195,7 +196,7 @@ private:
}
return ret;
}
static vector<Register> registersToSave(QCall &q) {
static vector<Register> registersToSave(Quadruple &q) {
return aliveAfter(q, Register::callerSaved);
}
};
......
......@@ -48,7 +48,19 @@ size_t ClassInfo::calculateSize() {
size += var->type->size();
}
auto parent = getClassParent();
if (parent) functionCount = parent->functionCount;
for (const auto& f : functions) {
if (parent) {
if (auto pv = parent->functions.find(f->name)) {
// verify types
if (!f->type->isEqual(pv->type, true)) {
throw InvalidTypeError(*f->type, {pv->type}, f->ident);
}
f->offset = pv->offset;
continue;
}
}
f->offset = functionCount++;
}
......
......@@ -63,6 +63,7 @@ public:
virtual ~Binding() {};
BindingPtr getParent() { return parent; };
ClassInfoPtr getClassParent() { return dynamic_pointer_cast<ClassInfo>(parent); };
};
class ClassInfo : public VarInfo, public Binding
......@@ -72,7 +73,6 @@ public:
ClassInfo(PIdent *ident, BindingPtr parent = nullptr);
virtual string kind() const { return "class"; }
ClassInfoPtr getClassParent() { return dynamic_pointer_cast<ClassInfo>(parent); };
size_t calculateSize();
size_t size, functionCount;
};
......
......@@ -31,10 +31,17 @@ public:
}
TPtr local(string name) const {
const auto p = this->find(name);
const auto p = set<TPtr, Compare<TPtr>>::find(name);
return p != this->end() ? *p : nullptr;
}
TPtr find(string name) const {
const auto p = set<TPtr, Compare<TPtr>>::find(name);
if (p != this->end()) return *p;
if (parent) return parent->find(name);
return nullptr;
}
void add(TPtr obj) {
if (broader) {
broader->add(obj);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment