From 53de62a486c1f6daeedb90289ec145f4e7f73a8d Mon Sep 17 00:00:00 2001 From: Klaas Boesche Date: Fri, 6 Nov 2015 15:12:10 +0000 Subject: Compile list literals to byte code. -- MOS_MIGRATED_REVID=107231604 --- .../devtools/build/lib/syntax/ListLiteral.java | 60 ++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'src/main/java/com/google/devtools/build/lib/syntax/ListLiteral.java') diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ListLiteral.java b/src/main/java/com/google/devtools/build/lib/syntax/ListLiteral.java index 13c4d010b0..18484cccb9 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/ListLiteral.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/ListLiteral.java @@ -13,8 +13,22 @@ // limitations under the License. package com.google.devtools.build.lib.syntax; +import static com.google.devtools.build.lib.syntax.compiler.ByteCodeUtils.append; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.syntax.SkylarkList.MutableList; import com.google.devtools.build.lib.syntax.SkylarkList.Tuple; +import com.google.devtools.build.lib.syntax.compiler.ByteCodeMethodCalls; +import com.google.devtools.build.lib.syntax.compiler.ByteCodeUtils; +import com.google.devtools.build.lib.syntax.compiler.DebugInfo; +import com.google.devtools.build.lib.syntax.compiler.DebugInfo.AstAccessors; +import com.google.devtools.build.lib.syntax.compiler.NewObject; +import com.google.devtools.build.lib.syntax.compiler.VariableScope; + +import net.bytebuddy.implementation.bytecode.ByteCodeAppender; +import net.bytebuddy.implementation.bytecode.Duplication; import java.util.ArrayList; import java.util.Collections; @@ -102,4 +116,50 @@ public final class ListLiteral extends Expression { expr.validate(env); } } + + @Override + ByteCodeAppender compile(VariableScope scope, DebugInfo debugInfo) { + AstAccessors debugAccessors = debugInfo.add(this); + List listConstruction = new ArrayList<>(); + if (isTuple()) { + append(listConstruction, ByteCodeMethodCalls.BCImmutableList.builder); + } else { + append( + listConstruction, + // create a new MutableList object + NewObject.fromConstructor(MutableList.class, Mutability.class) + .arguments( + scope.loadEnvironment(), ByteCodeUtils.invoke(Environment.class, "mutability"))); + } + + for (Expression expression : exprs) { + Preconditions.checkNotNull( + expression, "List literal at %s contains null expression", getLocation()); + ByteCodeAppender compiledValue = expression.compile(scope, debugInfo); + if (isTuple()) { + listConstruction.add(compiledValue); + append( + listConstruction, + // this re-adds the builder to the stack and we reuse it in the next iteration/after + ByteCodeMethodCalls.BCImmutableList.Builder.add); + } else { + // duplicate the list reference on the stack for reuse in the next iteration/after + append(listConstruction, Duplication.SINGLE); + listConstruction.add(compiledValue); + append( + listConstruction, + debugAccessors.loadLocation, + scope.loadEnvironment(), + ByteCodeUtils.cleanInvoke( + MutableList.class, "add", Object.class, Location.class, Environment.class)); + } + } + if (isTuple()) { + append( + listConstruction, + ByteCodeMethodCalls.BCImmutableList.Builder.build, + ByteCodeUtils.invoke(Tuple.class, "create", ImmutableList.class)); + } + return ByteCodeUtils.compoundAppender(listConstruction); + } } -- cgit v1.2.3