mirror of
https://github.com/apple/pkl.git
synced 2026-01-11 14:20:35 +01:00
Add optimization for generator bodies that don't introduce new members (#1013)
If a generator object literal doesn't add any object members, we can simply use the parent in its place. Co-authored-by: Kushal Pisavadia <kushi.p@gmail.com>
This commit is contained in:
@@ -73,6 +73,9 @@ public abstract class GeneratorObjectLiteralNode extends ObjectLiteralNode {
|
||||
@Specialization(guards = "checkObjectCannotHaveParameters()")
|
||||
protected VmDynamic evalDynamic(VirtualFrame frame, VmDynamic parent) {
|
||||
var data = executeChildren(frame, parent, parent.getLength());
|
||||
if (data.hasNoMembers()) {
|
||||
return parent;
|
||||
}
|
||||
var result = new VmDynamic(frame.materialize(), parent, data.members(), data.length());
|
||||
return data.storeGeneratorFrames(result);
|
||||
}
|
||||
@@ -81,6 +84,9 @@ public abstract class GeneratorObjectLiteralNode extends ObjectLiteralNode {
|
||||
protected VmTyped evalTyped(VirtualFrame frame, VmTyped parent) {
|
||||
VmUtils.checkIsInstantiable(parent.getVmClass(), getParentNode());
|
||||
var data = executeChildren(frame, parent, 0);
|
||||
if (data.hasNoMembers()) {
|
||||
return parent;
|
||||
}
|
||||
assert data.hasNoGeneratorFrames();
|
||||
return new VmTyped(frame.materialize(), parent, parent.getVmClass(), data.members());
|
||||
}
|
||||
@@ -88,6 +94,9 @@ public abstract class GeneratorObjectLiteralNode extends ObjectLiteralNode {
|
||||
@Specialization(guards = "checkListingCannotHaveParameters()")
|
||||
protected VmListing evalListing(VirtualFrame frame, VmListing parent) {
|
||||
var data = executeChildren(frame, parent, parent.getLength());
|
||||
if (data.hasNoMembers()) {
|
||||
return parent;
|
||||
}
|
||||
var result = new VmListing(frame.materialize(), parent, data.members(), data.length());
|
||||
return data.storeGeneratorFrames(result);
|
||||
}
|
||||
@@ -95,6 +104,9 @@ public abstract class GeneratorObjectLiteralNode extends ObjectLiteralNode {
|
||||
@Specialization(guards = "checkMappingCannotHaveParameters()")
|
||||
protected VmMapping evalMapping(VirtualFrame frame, VmMapping parent) {
|
||||
var data = executeChildren(frame, parent, 0);
|
||||
if (data.hasNoMembers()) {
|
||||
return parent;
|
||||
}
|
||||
var result = new VmMapping(frame.materialize(), parent, data.members());
|
||||
return data.storeGeneratorFrames(result);
|
||||
}
|
||||
@@ -118,6 +130,9 @@ public abstract class GeneratorObjectLiteralNode extends ObjectLiteralNode {
|
||||
@Specialization(guards = {"parent == getDynamicClass()", "checkObjectCannotHaveParameters()"})
|
||||
protected VmDynamic evalDynamicClass(VirtualFrame frame, VmClass parent) {
|
||||
var data = executeChildren(frame, parent, 0);
|
||||
if (data.hasNoMembers()) {
|
||||
return VmDynamic.empty();
|
||||
}
|
||||
var result =
|
||||
new VmDynamic(frame.materialize(), parent.getPrototype(), data.members(), data.length());
|
||||
return data.storeGeneratorFrames(result);
|
||||
@@ -126,6 +141,9 @@ public abstract class GeneratorObjectLiteralNode extends ObjectLiteralNode {
|
||||
@Specialization(guards = {"parent == getMappingClass()", "checkMappingCannotHaveParameters()"})
|
||||
protected VmMapping evalMappingClass(VirtualFrame frame, VmClass parent) {
|
||||
var data = executeChildren(frame, parent, 0);
|
||||
if (data.hasNoMembers()) {
|
||||
return VmMapping.empty();
|
||||
}
|
||||
var result = new VmMapping(frame.materialize(), parent.getPrototype(), data.members());
|
||||
return data.storeGeneratorFrames(result);
|
||||
}
|
||||
@@ -133,6 +151,9 @@ public abstract class GeneratorObjectLiteralNode extends ObjectLiteralNode {
|
||||
@Specialization(guards = {"parent == getListingClass()", "checkListingCannotHaveParameters()"})
|
||||
protected VmListing evalListingClass(VirtualFrame frame, VmClass parent) {
|
||||
var data = executeChildren(frame, parent, 0);
|
||||
if (data.hasNoMembers()) {
|
||||
return VmListing.empty();
|
||||
}
|
||||
var result =
|
||||
new VmListing(frame.materialize(), parent.getPrototype(), data.members(), data.length());
|
||||
return data.storeGeneratorFrames(result);
|
||||
@@ -142,6 +163,9 @@ public abstract class GeneratorObjectLiteralNode extends ObjectLiteralNode {
|
||||
protected VmTyped evalTypedObjectClass(VirtualFrame frame, VmClass parent) {
|
||||
VmUtils.checkIsInstantiable(parent, getParentNode());
|
||||
var data = executeChildren(frame, parent, 0);
|
||||
if (data.hasNoMembers()) {
|
||||
return parent.getPrototype();
|
||||
}
|
||||
assert data.hasNoGeneratorFrames();
|
||||
return new VmTyped(frame.materialize(), parent.getPrototype(), parent, data.members());
|
||||
}
|
||||
|
||||
@@ -55,6 +55,10 @@ public final class ObjectData {
|
||||
return length;
|
||||
}
|
||||
|
||||
boolean hasNoMembers() {
|
||||
return members.isEmpty();
|
||||
}
|
||||
|
||||
boolean hasNoGeneratorFrames() {
|
||||
return generatorFrames.isEmpty();
|
||||
}
|
||||
|
||||
46
pkl-core/src/test/files/LanguageSnippetTests/input/generators/generatorNoMembers.pkl
vendored
Normal file
46
pkl-core/src/test/files/LanguageSnippetTests/input/generators/generatorNoMembers.pkl
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
// should only result in one trace in the output; generator object literals that don't add any
|
||||
// members should be optimized away.
|
||||
res1 {
|
||||
prop = trace("hello")
|
||||
}
|
||||
|
||||
res2 = (res1) {
|
||||
when (false) {
|
||||
prop2 = 2
|
||||
}
|
||||
}
|
||||
|
||||
res3 = (res1) {
|
||||
for (_ in List()) {
|
||||
"hello"
|
||||
}
|
||||
}
|
||||
|
||||
res4 = (res1) {
|
||||
...List()
|
||||
}
|
||||
|
||||
res5 = (res1) {
|
||||
when (true) {
|
||||
} else {
|
||||
prop3 = 3
|
||||
}
|
||||
}
|
||||
|
||||
res6 = (Dynamic) {
|
||||
when (true) {}
|
||||
}
|
||||
|
||||
res7 = (Mapping) {
|
||||
when (true) {}
|
||||
}
|
||||
|
||||
class Person {}
|
||||
|
||||
res8 = (Person) {
|
||||
when (true) {}
|
||||
}
|
||||
|
||||
res9 = (Listing) {
|
||||
when (true) {}
|
||||
}
|
||||
20
pkl-core/src/test/files/LanguageSnippetTests/output/generators/generatorNoMembers.err
vendored
Normal file
20
pkl-core/src/test/files/LanguageSnippetTests/output/generators/generatorNoMembers.err
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
res1 {
|
||||
prop = "hello"
|
||||
}
|
||||
res2 {
|
||||
prop = "hello"
|
||||
}
|
||||
res3 {
|
||||
prop = "hello"
|
||||
}
|
||||
res4 {
|
||||
prop = "hello"
|
||||
}
|
||||
res5 {
|
||||
prop = "hello"
|
||||
}
|
||||
res6 {}
|
||||
res7 {}
|
||||
res8 {}
|
||||
res9 {}
|
||||
pkl: TRACE: "hello" = "hello" (file:///$snippetsDir/input/generators/generatorNoMembers.pkl)
|
||||
Reference in New Issue
Block a user