Skip to content

Commit 7aeb94f

Browse files
authored
Override objmods (#1190)
* native access for wrappers * simply override objmods if redefined in code * and some validation performance * fixes * review fix
1 parent c8331bd commit 7aeb94f

12 files changed

Lines changed: 225 additions & 16 deletions

File tree

Wurstpack/wurstscript/grill

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ if [[ ! -x "$RUNTIME" ]]; then
2323
exit 3
2424
fi
2525

26-
exec "$RUNTIME" -Dfile.encoding=UTF-8 -jar "$JAR" "$@"
26+
exec "$RUNTIME" -Dfile.encoding=UTF-8 --enable-native-access=ALL-UNNAMED -jar "$JAR" "$@"

Wurstpack/wurstscript/grill.cmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ if not exist "%JAVA%" (
3131
goto :restore
3232
)
3333

34-
"%JAVA%" -Dfile.encoding=UTF-8 -jar "%GRILL_JAR%" %*
34+
"%JAVA%" -Dfile.encoding=UTF-8 --enable-native-access=ALL-UNNAMED -jar "%GRILL_JAR%" %*
3535

3636
:restore
3737
rem Restore previous code page if we captured it

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/intermediateLang/interpreter/CompiletimeNatives.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ public ILconstTuple createObjectDefinition(ILconstString fileType, ILconstInt ne
4141
String objIdString = ObjectHelper.objectIdIntToString(newUnitId.getVal());
4242
boolean isMeleeOverride = newUnitId.getVal() == deriveFrom.getVal();
4343

44-
if (!isMeleeOverride && dataStore.getObjs().containsKey(ObjId.valueOf(objIdString))) {
45-
globalState.compilationError("Object definition with id " + objIdString + " already exists.");
44+
if (!isMeleeOverride && !globalState.registerCreatedObjectDefinition(fileType.getVal(), objIdString)) {
45+
globalState.compilationError("Object definition with id " + objIdString + " is defined more than once.");
4646
}
4747
ObjMod.Obj objDef = newDefFromFiletype(dataStore, deriveFrom.getVal(), newUnitId.getVal(), isMeleeOverride);
4848
if (!isMeleeOverride) {
@@ -59,10 +59,15 @@ private ObjMod.Obj newDefFromFiletype(ObjMod<? extends ObjMod.Obj> dataStore, in
5959
if (isMeleeOverride) {
6060
ObjId id = ObjId.valueOf(ObjectHelper.objectIdIntToString(newId));
6161
// same id => modify melee/original definition table
62+
ObjMod.Obj existing = dataStore.getObjs().get(id);
63+
if (existing != null) {
64+
return existing;
65+
}
6266
return dataStore.addObj(id, null);
6367
}
6468
ObjId baseIdS = ObjId.valueOf(ObjectHelper.objectIdIntToString(base));
6569
ObjId newIdS = ObjId.valueOf(ObjectHelper.objectIdIntToString(newId));
70+
dataStore.removeObj(newIdS);
6671
return dataStore.addObj(newIdS, baseIdS);
6772
}
6873

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/intermediateLang/interpreter/ProgramStateIO.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class ProgramStateIO extends ProgramState {
3636
private @Nullable final MpqEditor mpqEditor;
3737
private final Map<ObjectFileType, ObjMod<? extends ObjMod.Obj>> dataStoreMap = Maps.newLinkedHashMap();
3838
private final Map<ObjectFileType, String> dataStoreHashes = Maps.newLinkedHashMap();
39+
private final Map<String, Set<String>> createdObjectDefinitionIds = Maps.newLinkedHashMap();
3940
private int id = 0;
4041
private final Map<String, ObjMod.Obj> objDefinitions = Maps.newLinkedHashMap();
4142
private PrintStream outStream = System.err;
@@ -368,6 +369,11 @@ ObjMod.Obj getObjectDefinition(String key) {
368369
return objDefinitions.get(key);
369370
}
370371

372+
boolean registerCreatedObjectDefinition(String fileExtension, String objId) {
373+
Set<String> ids = createdObjectDefinitionIds.computeIfAbsent(fileExtension, k -> new LinkedHashSet<>());
374+
return ids.add(objId);
375+
}
376+
371377
/**
372378
* Calculate hash of an object file's contents
373379
*/

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/languageserver/ModelManagerImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ public Changes removeCompilationUnit(WFile resource) {
9696
toRemove.add(compilationUnit);
9797
}
9898
}
99+
GlobalCaches.clearLookupCacheFor(toRemove);
99100
model2.removeAll(toRemove);
100101
}
101102

@@ -419,6 +420,7 @@ private void updateModel(CompilationUnit cu, WurstGui gui) {
419420
Set<String> oldPackages = providedPackages(c);
420421
Set<CompilationUnit> mustUpdate = calculateCUsToUpdate(Collections.singletonList(cu), oldPackages, model2);
421422

423+
GlobalCaches.clearLookupCacheFor(Collections.singletonList(c));
422424
clearCompilationUnits(mustUpdate);
423425
// replace old compilationunit with new one:
424426
it.set(cu);

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/WurstChecker.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import de.peeeq.wurstscript.attributes.ErrorHandler;
77
import de.peeeq.wurstscript.attributes.names.DesugarArrayLength;
88
import de.peeeq.wurstscript.gui.WurstGui;
9+
import de.peeeq.wurstscript.validation.GlobalCaches;
910
import de.peeeq.wurstscript.validation.TRVEHelper;
1011
import de.peeeq.wurstscript.validation.WurstValidator;
1112

@@ -34,6 +35,7 @@ public void checkProg(WurstModel root, Collection<CompilationUnit> toCheck) {
3435
if (errorHandler.getErrorCount() > 0) return;
3536

3637
attachErrorHandler(root);
38+
clearGlobalCaches(root, toCheck);
3739

3840
expandModules(root);
3941

@@ -50,6 +52,14 @@ public void checkProg(WurstModel root, Collection<CompilationUnit> toCheck) {
5052
validator.validate(toCheck);
5153
}
5254

55+
private void clearGlobalCaches(WurstModel root, Collection<CompilationUnit> toCheck) {
56+
if (toCheck == root || toCheck.size() >= root.size()) {
57+
GlobalCaches.clearAll();
58+
} else {
59+
GlobalCaches.clearLookupCacheFor(toCheck);
60+
}
61+
}
62+
5363
private void attachErrorHandler(WurstModel root) {
5464
for (CompilationUnit cu : root) {
5565
cu.getCuInfo().setCuErrorHandler(errorHandler);

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/attributes/names/Exports.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ public static ImmutableMultimap<String, TypeLink> exportedTypeNameLinks(WPackage
5353
return result.build();
5454
}
5555

56-
5756
private static void addExportedTypeNameLinks(Builder<String, TypeLink> result, WPackage p, Set<WPackage> alreadyImported) {
5857
if (alreadyImported.contains(p)) {
5958
return;

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/attributes/names/NameLinks.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,6 @@ public static ImmutableMultimap<String, DefLink> calculate(WPackage p) {
268268
return result.build();
269269
}
270270

271-
272271
public static ImmutableMultimap<String, DefLink> calculate(WEntities wEntities) {
273272
ImmutableMultimap.Builder<String, DefLink> result = ImmutableSetMultimap.builder();
274273
for (WEntity e : wEntities) {

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/validation/GlobalCaches.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@
66
import de.peeeq.wurstscript.intermediatelang.interpreter.LocalState;
77
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
88

9+
import java.util.ArrayDeque;
910
import java.util.Arrays;
11+
import java.util.Collection;
12+
import java.util.IdentityHashMap;
1013
import java.util.Map;
14+
import java.util.Set;
1115
import java.util.concurrent.atomic.AtomicLong;
1216

1317
// Expose static fields only if you already have them there; otherwise, just clear via dedicated methods.
@@ -146,6 +150,28 @@ public static void clearAll() {
146150
HasAnnotation.clearCaches();
147151
}
148152

153+
/**
154+
* Clears lookup entries whose query element belongs to one of the changed roots.
155+
* This keeps editor validation from throwing away hot lookup data for unchanged files.
156+
*/
157+
public static void clearLookupCacheFor(Collection<? extends Element> roots) {
158+
if (roots.isEmpty()) {
159+
return;
160+
}
161+
Set<Element> affected = java.util.Collections.newSetFromMap(new IdentityHashMap<>());
162+
ArrayDeque<Element> todo = new ArrayDeque<>(roots);
163+
while (!todo.isEmpty()) {
164+
Element e = todo.removeLast();
165+
if (!affected.add(e)) {
166+
continue;
167+
}
168+
for (int i = 0; i < e.size(); i++) {
169+
todo.add(e.get(i));
170+
}
171+
}
172+
lookupCache.keySet().removeIf(key -> affected.contains(key.element));
173+
}
174+
149175
public enum LookupType {
150176
FUNC, VAR, TYPE, PACKAGE, MEMBER_FUNC, MEMBER_VAR
151177
}

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/validation/WurstValidator.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,10 @@ public WurstValidator(WurstModel root) {
6464

6565
public void validate(Collection<CompilationUnit> toCheck) {
6666
try {
67-
functionCount = countFunctions();
67+
functionCount = countFunctions(toCheck);
6868
visitedFunctions = 0;
6969
heavyFunctions.clear();
7070
heavyBlocks.clear();
71-
GlobalCaches.clearAll();
7271

7372
lightValidation(toCheck);
7473

@@ -123,11 +122,6 @@ private void lightValidation(Collection<CompilationUnit> toCheck) {
123122
for (CompilationUnit cu : toCheck) {
124123
walkTree(cu);
125124
}
126-
127-
// Build CFG once for heavy phase (enables reachability/prev/next attrs)
128-
for (CompilationUnit cu : toCheck) {
129-
computeFlowAttributes(cu);
130-
}
131125
}
132126

133127
/** Visit only statements under root and run checkReachability where applicable. */
@@ -1174,16 +1168,19 @@ private void checkIntVal(ExprIntVal e) {
11741168
// check range? ...
11751169
}
11761170

1177-
private int countFunctions() {
1171+
private int countFunctions(Collection<CompilationUnit> toCheck) {
11781172
final int[] functionCount = new int[1];
1179-
prog.accept(new WurstModel.DefaultVisitor() {
1173+
Element.DefaultVisitor visitor = new Element.DefaultVisitor() {
11801174

11811175
@Override
11821176
public void visit(FuncDef f) {
11831177
super.visit(f);
11841178
functionCount[0]++;
11851179
}
1186-
});
1180+
};
1181+
for (CompilationUnit cu : toCheck) {
1182+
cu.accept(visitor);
1183+
}
11871184
return functionCount[0];
11881185
}
11891186

0 commit comments

Comments
 (0)