Skip to content

Commit f0a2932

Browse files
committed
Recycle object ids in the interpreter like in JASS
1 parent 73d03c8 commit f0a2932

5 files changed

Lines changed: 364 additions & 39 deletions

File tree

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/CompiletimeFunctionRunner.java

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import de.peeeq.wurstscript.jassinterpreter.TestFailException;
2727
import de.peeeq.wurstscript.jassinterpreter.TestSuccessException;
2828
import de.peeeq.wurstscript.parser.WPos;
29+
import de.peeeq.wurstscript.translation.imtranslation.ClassManagementVars;
2930
import de.peeeq.wurstscript.translation.imtranslation.*;
3031
import de.peeeq.wurstscript.types.TypesHelper;
3132
import de.peeeq.wurstscript.utils.Pair;
@@ -51,6 +52,7 @@ public class CompiletimeFunctionRunner {
5152
private final ImTranslator translator;
5253
private boolean injectObjects;
5354
private final Deque<Runnable> delayedActions = new ArrayDeque<>();
55+
private final Map<ClassManagementVars, List<CompiletimeObjectInit>> compiletimeObjects = new LinkedHashMap<>();
5456

5557
public ILInterpreter getInterpreter() {
5658
return interpreter;
@@ -110,6 +112,7 @@ public void run() {
110112
interpreter.writebackGlobalState(isInjectObjects());
111113
}
112114
runDelayedActions();
115+
emitCompiletimeObjectAllocs();
113116

114117
partitionCompiletimeStateInitFunction();
115118

@@ -272,10 +275,10 @@ public ImVar initFor(ILconstObject obj) {
272275

273276
ImVar res = JassIm.ImVar(obj.getTrace(), obj.getType(), obj.getType() + "_compiletime", false);
274277
imProg.getGlobals().add(res);
275-
ImAlloc alloc = JassIm.ImAlloc(obj.getTrace(), obj.getType());
276-
addCompiletimeStateInitAlloc(alloc.getTrace(), res, alloc);
277278
globalState.setVal(res, obj);
278279

280+
registerCompiletimeObject(obj, res);
281+
279282

280283
Element trace = obj.getTrace();
281284

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

371374
}
372375

376+
private void registerCompiletimeObject(ILconstObject obj, ImVar targetVar) {
377+
ClassManagementVars mVars = translator.getClassManagementVarsFor(obj.getType().getClassDef());
378+
compiletimeObjects.computeIfAbsent(mVars, k -> new ArrayList<>())
379+
.add(new CompiletimeObjectInit(obj, targetVar));
380+
}
381+
382+
private void emitCompiletimeObjectAllocs() {
383+
if (compiletimeObjects.isEmpty()) {
384+
return;
385+
}
386+
387+
List<ImStmt> objectInits = new ArrayList<>();
388+
389+
for (Map.Entry<ClassManagementVars, List<CompiletimeObjectInit>> entry : compiletimeObjects.entrySet()) {
390+
List<CompiletimeObjectInit> objs = entry.getValue();
391+
if (objs.isEmpty()) {
392+
continue;
393+
}
394+
395+
objs.sort(Comparator.comparingInt(o -> o.object.getObjectId()));
396+
397+
ClassManagementVars mVars = entry.getKey();
398+
int currentMax = 0;
399+
int finalMax = globalState.getMaxAllocatedId(objs.get(0).object.getImClass());
400+
401+
for (CompiletimeObjectInit init : objs) {
402+
int desiredId = init.object.getObjectId();
403+
int targetMax = desiredId - 1;
404+
if (targetMax > currentMax) {
405+
objectInits.add(JassIm.ImSet(init.object.getTrace(),
406+
JassIm.ImVarAccess(mVars.maxIndex),
407+
JassIm.ImIntVal(targetMax)));
408+
currentMax = targetMax;
409+
}
410+
411+
ImAlloc alloc = JassIm.ImAlloc(init.object.getTrace(), init.object.getType());
412+
ImSet assign = JassIm.ImSet(init.object.getTrace(), JassIm.ImVarAccess(init.targetVar), alloc);
413+
objectInits.add(assign);
414+
imProg.getGlobalInits().put(init.targetVar, Collections.singletonList(assign));
415+
currentMax = desiredId;
416+
}
417+
418+
if (finalMax > currentMax) {
419+
objectInits.add(JassIm.ImSet(objs.get(0).object.getTrace(),
420+
JassIm.ImVarAccess(mVars.maxIndex), JassIm.ImIntVal(finalMax)));
421+
}
422+
}
423+
424+
getCompiletimeStateInitFunction().getBody().addAll(0, objectInits);
425+
}
426+
427+
private static class CompiletimeObjectInit {
428+
private final ILconstObject object;
429+
private final ImVar targetVar;
430+
431+
private CompiletimeObjectInit(ILconstObject object, ImVar targetVar) {
432+
this.object = object;
433+
this.targetVar = targetVar;
434+
}
435+
}
436+
373437
private ImFunction compiletimeStateInitFunction = null;
374438

375439
private ImFunction getCompiletimeStateInitFunction() {

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/intermediatelang/interpreter/EvaluateExpr.java

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,11 @@ public static ILconst eval(ImVarArrayAccess e, ProgramState globalState, LocalSt
195195

196196
public static @Nullable ILconst eval(ImMethodCall mc,
197197
ProgramState globalState, LocalState localState) {
198-
ILconstObject receiver = globalState.toObject(mc.getReceiver().evaluate(globalState, localState));
198+
ImType receiverType = globalState.resolveType(mc.getReceiver().attrTyp());
199+
ImClassType receiverClassType = receiverType instanceof ImClassType
200+
? (ImClassType) receiverType
201+
: mc.getMethod().getMethodClass();
202+
ILconstObject receiver = globalState.toObject(mc.getReceiver().evaluate(globalState, localState), receiverClassType);
199203
globalState.assertAllocated(receiver, mc.attrTrace());
200204
mark(mc, globalState);
201205

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

232236

233237
public static ILconst eval(ImMemberAccess ma, ProgramState globalState, LocalState localState) {
234-
ILconstObject receiver = globalState.toObject(ma.getReceiver().evaluate(globalState, localState));
238+
ImType receiverType = globalState.resolveType(ma.getReceiver().attrTyp());
239+
ImClassType receiverClassType = receiverType instanceof ImClassType ? (ImClassType) receiverType : null;
240+
if (receiverClassType == null) {
241+
de.peeeq.wurstscript.jassIm.Element parent = ma.getVar().getParent();
242+
while (parent != null && !(parent instanceof ImClass)) {
243+
parent = parent.getParent();
244+
}
245+
if (parent instanceof ImClass) {
246+
receiverClassType = JassIm.ImClassType((ImClass) parent, JassIm.ImTypeArguments());
247+
}
248+
}
249+
250+
ILconstObject receiver = globalState.toObject(ma.getReceiver().evaluate(globalState, localState), receiverClassType);
235251
if (receiver == null) {
236252
throw new InterpreterException(ma.getTrace(), "Null pointer dereference: " + ImPrinter.asString(ma.getReceiver()));
237253
}
@@ -254,14 +270,14 @@ public static ILconst eval(ImAlloc e, ProgramState globalState, LocalState local
254270

255271
public static ILconst eval(ImDealloc imDealloc, ProgramState globalState,
256272
LocalState localState) {
257-
ILconstObject obj = globalState.toObject(imDealloc.getObj().evaluate(globalState, localState));
273+
ILconstObject obj = globalState.toObject(imDealloc.getObj().evaluate(globalState, localState), imDealloc.getClazz());
258274
globalState.deallocate(obj, imDealloc.getClazz().getClassDef(), imDealloc.attrTrace());
259275
return ILconstNull.instance();
260276
}
261277

262278
public static ILconst eval(ImInstanceof e, ProgramState globalState,
263279
LocalState localState) {
264-
ILconstObject obj = globalState.toObject(e.getObj().evaluate(globalState, localState));
280+
ILconstObject obj = globalState.toObject(e.getObj().evaluate(globalState, localState), e.getClazz());
265281
return ILconstBool.instance(globalState.isInstanceOf(obj, e.getClazz().getClassDef(), e.attrTrace()));
266282
}
267283

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

273289
public static ILconst eval(ImTypeIdOfObj e,
274290
ProgramState globalState, LocalState localState) {
275-
ILconstObject obj = globalState.toObject(e.getObj().evaluate(globalState, localState));
291+
ILconstObject obj = globalState.toObject(e.getObj().evaluate(globalState, localState), e.getClazz());
276292
return new ILconstInt(globalState.getTypeId(obj, e.attrTrace()));
277293
}
278294

@@ -376,13 +392,14 @@ public ILconst get() {
376392

377393
public static ILaddress evaluateLvalue(ImMemberAccess va, ProgramState globalState, LocalState localState) {
378394
ImVar v = va.getVar();
395+
ImType receiverType = globalState.resolveType(va.getReceiver().attrTyp());
396+
ImClassType receiverClassType = receiverType instanceof ImClassType ? (ImClassType) receiverType : null;
379397
ILconst receiverVal = va.getReceiver().evaluate(globalState, localState);
380-
ILconstObject receiver = globalState.toObject(receiverVal);
381-
if (receiver == null && receiverVal instanceof ILconstInt && va.getReceiver().attrTyp() instanceof ImClassType) {
398+
ILconstObject receiver = globalState.toObject(receiverVal, receiverClassType);
399+
if (receiver == null && receiverVal instanceof ILconstInt && receiverClassType != null) {
382400
int objectId = ((ILconstInt) receiverVal).getVal();
383401
if (objectId != 0) {
384-
receiver = globalState.ensureObject((ImClassType) va.getReceiver().attrTyp(),
385-
objectId, va.attrTrace());
402+
receiver = globalState.ensureObject(receiverClassType, objectId, va.attrTrace());
386403
}
387404
}
388405
if (receiver == null) {
@@ -443,7 +460,9 @@ public static ILconst eval(ImTypeVarDispatch e, ProgramState globalState, LocalS
443460

444461
public static ILconst eval(ImCast imCast, ProgramState globalState, LocalState localState) {
445462
ILconst res = imCast.getExpr().evaluate(globalState, localState);
446-
if (TypesHelper.isIntType(imCast.getToType())) {
463+
ImType targetType = globalState.resolveType(imCast.getToType());
464+
465+
if (TypesHelper.isIntType(targetType)) {
447466
if (res instanceof ILconstObject) {
448467
return ILconstInt.create(((ILconstObject) res).getObjectId());
449468
}
@@ -454,10 +473,10 @@ public static ILconst eval(ImCast imCast, ProgramState globalState, LocalState l
454473
}
455474
}
456475
if (res instanceof ILconstInt) {
457-
if (imCast.getToType() instanceof ImClassType) {
458-
return globalState.getObjectByIndex(((ILconstInt) res).getVal());
476+
if (targetType instanceof ImClassType) {
477+
return globalState.getObjectByIndex(((ILconstInt) res).getVal(), (ImClassType) targetType);
459478
}
460-
if (imCast.getToType() instanceof IlConstHandle) {
479+
if (targetType instanceof IlConstHandle) {
461480
return globalState.getHandleByIndex(((ILconstInt) res).getVal());
462481
}
463482
}

0 commit comments

Comments
 (0)