Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import de.peeeq.wurstscript.jassinterpreter.TestFailException;
import de.peeeq.wurstscript.jassinterpreter.TestSuccessException;
import de.peeeq.wurstscript.parser.WPos;
import de.peeeq.wurstscript.translation.imtranslation.ClassManagementVars;
import de.peeeq.wurstscript.translation.imtranslation.*;
import de.peeeq.wurstscript.types.TypesHelper;
import de.peeeq.wurstscript.utils.Pair;
Expand All @@ -51,6 +52,7 @@ public class CompiletimeFunctionRunner {
private final ImTranslator translator;
private boolean injectObjects;
private final Deque<Runnable> delayedActions = new ArrayDeque<>();
private final Map<ClassManagementVars, List<CompiletimeObjectInit>> compiletimeObjects = new LinkedHashMap<>();

public ILInterpreter getInterpreter() {
return interpreter;
Expand Down Expand Up @@ -110,6 +112,7 @@ public void run() {
interpreter.writebackGlobalState(isInjectObjects());
}
runDelayedActions();
emitCompiletimeObjectAllocs();

partitionCompiletimeStateInitFunction();

Expand Down Expand Up @@ -272,10 +275,10 @@ public ImVar initFor(ILconstObject obj) {

ImVar res = JassIm.ImVar(obj.getTrace(), obj.getType(), obj.getType() + "_compiletime", false);
imProg.getGlobals().add(res);
ImAlloc alloc = JassIm.ImAlloc(obj.getTrace(), obj.getType());
addCompiletimeStateInitAlloc(alloc.getTrace(), res, alloc);
globalState.setVal(res, obj);

registerCompiletimeObject(obj, res);


Element trace = obj.getTrace();

Expand Down Expand Up @@ -370,6 +373,67 @@ private ImExpr constantToExpr(Element trace, ILconst value) {

}

private void registerCompiletimeObject(ILconstObject obj, ImVar targetVar) {
ClassManagementVars mVars = translator.getClassManagementVarsFor(obj.getType().getClassDef());
compiletimeObjects.computeIfAbsent(mVars, k -> new ArrayList<>())
.add(new CompiletimeObjectInit(obj, targetVar));
}

private void emitCompiletimeObjectAllocs() {
if (compiletimeObjects.isEmpty()) {
return;
}

List<ImStmt> objectInits = new ArrayList<>();

for (Map.Entry<ClassManagementVars, List<CompiletimeObjectInit>> entry : compiletimeObjects.entrySet()) {
List<CompiletimeObjectInit> objs = entry.getValue();
if (objs.isEmpty()) {
continue;
}

objs.sort(Comparator.comparingInt(o -> o.object.getObjectId()));

ClassManagementVars mVars = entry.getKey();
int currentMax = 0;
int finalMax = globalState.getMaxAllocatedId(objs.get(0).object.getImClass());

for (CompiletimeObjectInit init : objs) {
int desiredId = init.object.getObjectId();
int targetMax = desiredId - 1;
if (targetMax > currentMax) {
objectInits.add(JassIm.ImSet(init.object.getTrace(),
JassIm.ImVarAccess(mVars.maxIndex),
JassIm.ImIntVal(targetMax)));
currentMax = targetMax;
}

ImAlloc alloc = JassIm.ImAlloc(init.object.getTrace(), init.object.getType());
ImSet assign = JassIm.ImSet(init.object.getTrace(), JassIm.ImVarAccess(init.targetVar), alloc);
objectInits.add(assign);
imProg.getGlobalInits().put(init.targetVar, Collections.singletonList(assign));
currentMax = desiredId;
}

if (finalMax > currentMax) {
objectInits.add(JassIm.ImSet(objs.get(0).object.getTrace(),
JassIm.ImVarAccess(mVars.maxIndex), JassIm.ImIntVal(finalMax)));
}
}

getCompiletimeStateInitFunction().getBody().addAll(0, objectInits);
}

private static class CompiletimeObjectInit {
private final ILconstObject object;
private final ImVar targetVar;

private CompiletimeObjectInit(ILconstObject object, ImVar targetVar) {
this.object = object;
this.targetVar = targetVar;
}
}

private ImFunction compiletimeStateInitFunction = null;

private ImFunction getCompiletimeStateInitFunction() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,11 @@ public static ILconst eval(ImVarArrayAccess e, ProgramState globalState, LocalSt

public static @Nullable ILconst eval(ImMethodCall mc,
ProgramState globalState, LocalState localState) {
ILconstObject receiver = globalState.toObject(mc.getReceiver().evaluate(globalState, localState));
ImType receiverType = globalState.resolveType(mc.getReceiver().attrTyp());
ImClassType receiverClassType = receiverType instanceof ImClassType
? (ImClassType) receiverType
: mc.getMethod().getMethodClass();
ILconstObject receiver = globalState.toObject(mc.getReceiver().evaluate(globalState, localState), receiverClassType);
globalState.assertAllocated(receiver, mc.attrTrace());
mark(mc, globalState);

Expand Down Expand Up @@ -231,7 +235,19 @@ public static ILconst eval(ImVarArrayAccess e, ProgramState globalState, LocalSt


public static ILconst eval(ImMemberAccess ma, ProgramState globalState, LocalState localState) {
ILconstObject receiver = globalState.toObject(ma.getReceiver().evaluate(globalState, localState));
ImType receiverType = globalState.resolveType(ma.getReceiver().attrTyp());
ImClassType receiverClassType = receiverType instanceof ImClassType ? (ImClassType) receiverType : null;
if (receiverClassType == null) {
de.peeeq.wurstscript.jassIm.Element parent = ma.getVar().getParent();
while (parent != null && !(parent instanceof ImClass)) {
parent = parent.getParent();
}
if (parent instanceof ImClass) {
receiverClassType = JassIm.ImClassType((ImClass) parent, JassIm.ImTypeArguments());
}
}

ILconstObject receiver = globalState.toObject(ma.getReceiver().evaluate(globalState, localState), receiverClassType);
if (receiver == null) {
throw new InterpreterException(ma.getTrace(), "Null pointer dereference: " + ImPrinter.asString(ma.getReceiver()));
}
Expand All @@ -254,14 +270,14 @@ public static ILconst eval(ImAlloc e, ProgramState globalState, LocalState local

public static ILconst eval(ImDealloc imDealloc, ProgramState globalState,
LocalState localState) {
ILconstObject obj = globalState.toObject(imDealloc.getObj().evaluate(globalState, localState));
ILconstObject obj = globalState.toObject(imDealloc.getObj().evaluate(globalState, localState), imDealloc.getClazz());
globalState.deallocate(obj, imDealloc.getClazz().getClassDef(), imDealloc.attrTrace());
return ILconstNull.instance();
}

public static ILconst eval(ImInstanceof e, ProgramState globalState,
LocalState localState) {
ILconstObject obj = globalState.toObject(e.getObj().evaluate(globalState, localState));
ILconstObject obj = globalState.toObject(e.getObj().evaluate(globalState, localState), e.getClazz());
return ILconstBool.instance(globalState.isInstanceOf(obj, e.getClazz().getClassDef(), e.attrTrace()));
}

Expand All @@ -272,7 +288,7 @@ public static ILconst eval(ImTypeIdOfClass e,

public static ILconst eval(ImTypeIdOfObj e,
ProgramState globalState, LocalState localState) {
ILconstObject obj = globalState.toObject(e.getObj().evaluate(globalState, localState));
ILconstObject obj = globalState.toObject(e.getObj().evaluate(globalState, localState), e.getClazz());
return new ILconstInt(globalState.getTypeId(obj, e.attrTrace()));
}

Expand Down Expand Up @@ -376,13 +392,14 @@ public ILconst get() {

public static ILaddress evaluateLvalue(ImMemberAccess va, ProgramState globalState, LocalState localState) {
ImVar v = va.getVar();
ImType receiverType = globalState.resolveType(va.getReceiver().attrTyp());
ImClassType receiverClassType = receiverType instanceof ImClassType ? (ImClassType) receiverType : null;
ILconst receiverVal = va.getReceiver().evaluate(globalState, localState);
ILconstObject receiver = globalState.toObject(receiverVal);
if (receiver == null && receiverVal instanceof ILconstInt && va.getReceiver().attrTyp() instanceof ImClassType) {
ILconstObject receiver = globalState.toObject(receiverVal, receiverClassType);
if (receiver == null && receiverVal instanceof ILconstInt && receiverClassType != null) {
int objectId = ((ILconstInt) receiverVal).getVal();
if (objectId != 0) {
receiver = globalState.ensureObject((ImClassType) va.getReceiver().attrTyp(),
objectId, va.attrTrace());
receiver = globalState.ensureObject(receiverClassType, objectId, va.attrTrace());
}
}
if (receiver == null) {
Expand Down Expand Up @@ -443,7 +460,9 @@ public static ILconst eval(ImTypeVarDispatch e, ProgramState globalState, LocalS

public static ILconst eval(ImCast imCast, ProgramState globalState, LocalState localState) {
ILconst res = imCast.getExpr().evaluate(globalState, localState);
if (TypesHelper.isIntType(imCast.getToType())) {
ImType targetType = globalState.resolveType(imCast.getToType());

if (TypesHelper.isIntType(targetType)) {
if (res instanceof ILconstObject) {
return ILconstInt.create(((ILconstObject) res).getObjectId());
}
Expand All @@ -454,10 +473,10 @@ public static ILconst eval(ImCast imCast, ProgramState globalState, LocalState l
}
}
if (res instanceof ILconstInt) {
if (imCast.getToType() instanceof ImClassType) {
return globalState.getObjectByIndex(((ILconstInt) res).getVal());
if (targetType instanceof ImClassType) {
return globalState.getObjectByIndex(((ILconstInt) res).getVal(), (ImClassType) targetType);
}
if (imCast.getToType() instanceof IlConstHandle) {
if (targetType instanceof IlConstHandle) {
return globalState.getHandleByIndex(((ILconstInt) res).getVal());
}
}
Expand Down
Loading
Loading