mirror of
https://github.com/apple/pkl.git
synced 2026-03-20 08:14:15 +01:00
Fix encoding for mapping with local members (#1152)
Fixes an issue where local members are included in the mapping entry count. Also: avoid re-computing Mapping.length
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@ package org.pkl.core.runtime;
|
||||
|
||||
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
||||
import com.oracle.truffle.api.frame.MaterializedFrame;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
import org.graalvm.collections.UnmodifiableEconomicMap;
|
||||
@@ -25,10 +26,10 @@ import org.pkl.core.ast.member.ObjectMember;
|
||||
import org.pkl.core.util.CollectionUtils;
|
||||
import org.pkl.core.util.EconomicMaps;
|
||||
import org.pkl.core.util.LateInit;
|
||||
import org.pkl.core.util.MutableLong;
|
||||
|
||||
public final class VmMapping extends VmListingOrMapping {
|
||||
|
||||
private int cachedEntryCount = -1;
|
||||
private long cachedLength = -1;
|
||||
|
||||
@GuardedBy("this")
|
||||
private @LateInit VmSet __allKeys;
|
||||
@@ -124,7 +125,7 @@ public final class VmMapping extends VmListingOrMapping {
|
||||
// could use shallow force, but deep force is cached
|
||||
force(false);
|
||||
other.force(false);
|
||||
if (getEntryCount() != other.getEntryCount()) return false;
|
||||
if (getLength() != other.getLength()) return false;
|
||||
|
||||
var cursor = cachedValues.getEntries();
|
||||
while (cursor.advance()) {
|
||||
@@ -162,16 +163,21 @@ public final class VmMapping extends VmListingOrMapping {
|
||||
return result;
|
||||
}
|
||||
|
||||
// assumes mapping has been forced
|
||||
public int getEntryCount() {
|
||||
if (cachedEntryCount != -1) return cachedEntryCount;
|
||||
|
||||
var result = 0;
|
||||
for (var key : cachedValues.getKeys()) {
|
||||
if (key instanceof Identifier) continue;
|
||||
result += 1;
|
||||
}
|
||||
cachedEntryCount = result;
|
||||
return result;
|
||||
@TruffleBoundary
|
||||
public long getLength() {
|
||||
if (cachedLength != -1) return cachedLength;
|
||||
var count = new MutableLong(0);
|
||||
var visited = new HashSet<>();
|
||||
iterateMembers(
|
||||
(key, member) -> {
|
||||
var alreadyVisited = !visited.add(key);
|
||||
// important to record hidden member as visited before skipping it
|
||||
// because any overriding member won't carry a `hidden` identifier
|
||||
if (alreadyVisited || member.isLocalOrExternalOrHidden()) return true;
|
||||
count.getAndIncrement();
|
||||
return true;
|
||||
});
|
||||
cachedLength = count.get();
|
||||
return cachedLength;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.pkl.core.stdlib.base;
|
||||
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.IndirectCallNode;
|
||||
import java.util.HashSet;
|
||||
import org.pkl.core.ast.lambda.ApplyVmFunction1Node;
|
||||
import org.pkl.core.ast.lambda.ApplyVmFunction2Node;
|
||||
import org.pkl.core.ast.lambda.ApplyVmFunction2NodeGen;
|
||||
@@ -31,7 +30,6 @@ import org.pkl.core.stdlib.ExternalMethod2Node;
|
||||
import org.pkl.core.stdlib.ExternalPropertyNode;
|
||||
import org.pkl.core.util.EconomicMaps;
|
||||
import org.pkl.core.util.MutableBoolean;
|
||||
import org.pkl.core.util.MutableLong;
|
||||
import org.pkl.core.util.MutableReference;
|
||||
|
||||
public final class MappingNodes {
|
||||
@@ -53,20 +51,8 @@ public final class MappingNodes {
|
||||
|
||||
public abstract static class length extends ExternalPropertyNode {
|
||||
@Specialization
|
||||
@TruffleBoundary
|
||||
protected long eval(VmMapping self) {
|
||||
var count = new MutableLong(0);
|
||||
var visited = new HashSet<>();
|
||||
self.iterateMembers(
|
||||
(key, member) -> {
|
||||
var alreadyVisited = !visited.add(key);
|
||||
// important to record hidden member as visited before skipping it
|
||||
// because any overriding member won't carry a `hidden` identifier
|
||||
if (alreadyVisited || member.isLocalOrExternalOrHidden()) return true;
|
||||
count.getAndIncrement();
|
||||
return true;
|
||||
});
|
||||
return count.get();
|
||||
return self.getLength();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user