1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
#include "stdafx.h"
#include "TypeDtor.h"
#include "Type.h"
#include "Engine.h"
namespace storm {
Bool STORM_FN needsDestructor(Type *type) {
// A destructor is needed if any contained values have a destructor.
Array<MemberVar *> *vars = type->variables();
for (nat i = 0; i < vars->count(); i++) {
Value t = vars->at(i)->type;
if (!t.isValue())
continue;
Function *dtor = t.type->destructor();
if (dtor && !dtor->pure())
return true;
}
return false;
}
TypeDefaultDtor::TypeDefaultDtor(Type *owner)
: Function(Value(), new (owner) Str(Type::DTOR), new (owner) Array<Value>(1, thisPtr(owner))),
owner(owner) {
setCode(new (this) LazyCode(fnPtr(engine(), &TypeDefaultDtor::generate, this)));
}
Bool TypeDefaultDtor::pure() const {
Type *super = owner->super();
if (super) {
Function *dtor = super->destructor();
if (dtor && !dtor->pure())
return false;
}
return !needsDestructor(owner);
}
CodeGen *TypeDefaultDtor::generate() {
using namespace code;
CodeGen *t = new (this) CodeGen(runOn(), true, Value());
Listing *l = t->l;
Var me = l->createParam(engine().ptrDesc());
*l << prolog();
// Destroy all value variables.
Array<MemberVar *> *vars = owner->variables();
for (nat i = 0; i < vars->count(); i++) {
MemberVar *v = vars->at(i);
if (v->type.isAsmType())
continue;
Function *dtor = v->type.type->destructor();
if (!dtor)
continue;
*l << mov(ptrA, me);
*l << add(ptrA, ptrConst(v->offset()));
*l << fnParam(engine().ptrDesc(), ptrA);
*l << fnCall(dtor->ref(), true);
}
// Call super class' destructor (if any).
Type *super = owner->super();
if (super) {
Function *dtor = super->destructor();
if (dtor) {
*l << fnParam(engine().ptrDesc(), me);
*l << fnCall(dtor->directRef(), true);
}
}
*l << fnRet();
return t;
}
}
|