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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
#pragma once
#include "Core/TObject.h"
#include "Core/GcArray.h"
namespace storm {
STORM_PKG(core.lang);
class Type;
class Function;
class MemberVar;
/**
* Description of a type that needs to be rewritten. Expressed as a series of member copy
* operations, possibly in combination with initializations and destructors.
*/
class TypeTransform : public ObjectOn<Compiler> {
STORM_CLASS;
public:
// Create, specify `old` and `new` types.
STORM_CTOR TypeTransform(Type *oldType, Type *newType);
// Get the old and new types.
Type *STORM_FN oldType() const { return oldT; }
Type *STORM_FN newType() const { return newT; }
// Add a variable that has been added from `old` to `new`.
void STORM_FN added(MemberVar *var);
// Add a variable that has been removed from `old` to `new`.
void STORM_FN removed(MemberVar *var);
// Add a variable that is the same from `old` to `new`.
void STORM_FN same(MemberVar *o, MemberVar *n);
// Apply this transform to an object.
RootObject *apply(RootObject *old);
// Info in a plain C++ structure that can be used to transform offsets into the structure,
// and can be used while the GC is paused.
class Summary {
public:
// Size of the type itself.
size_t size;
// A single variable.
struct Var {
// Start offset.
size_t start;
// Size of the variable.
size_t size;
// Transformed offset.
size_t newStart;
// Compare them.
bool operator <(const Var &o) const {
return start < o.start;
}
bool operator <(size_t o) const {
return start < o;
}
};
// All variables, sorted to make lookup faster.
vector<Var> variables;
// Create.
Summary(size_t size, const vector<Var> &vars);
// Translate an offset.
size_t translate(size_t from) const;
};
// Create a summary.
Summary summary() const;
private:
// Old and new types.
Type *oldT;
Type *newT;
// Variables to handle.
struct MapItem {
// Old variable.
MemberVar *oldVar;
// New variable.
MemberVar *newVar;
// Cache of the function to call when applying the transform. Initially null.
Function *cache;
};
// Variables to manage.
GcArray<MapItem> *variables;
// Make sure 'variables' is large enough to hold at least one additional item.
void grow();
// Initialize a new variable.
void initVar(RootObject *object, MemberVar *var, Function *&cache);
// Copy a variable.
void copyVar(RootObject *to, MemberVar *toVar, RootObject *from, MemberVar *fromVar, Function *&cache);
};
}
|