Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 47 additions & 8 deletions java/src/com/google/template/soy/jbcsrc/ExpressionCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -1615,7 +1615,7 @@ private SoyExpression visitFieldAccess(SoyExpression baseExpr, FieldAccessNode n
if (sourceMethod != null) {
Optional<Extern> externApi = ExternAdaptors.asExtern(sourceMethod, args);
if (externApi.isPresent()) {
return callExtern(externApi.get(), args);
return callExtern(externApi.get(), args, node.getType());
}
return sourceFunctionCompiler.compile(node, sourceMethod, args, parameters, detacher);
}
Expand Down Expand Up @@ -1771,7 +1771,7 @@ var record = (RecordLiteralNode) node.getChild(1);
visitAllParams(node, ImmutableList.<SoyExpression>builder().add(baseExpr));
Optional<Extern> externApi = ExternAdaptors.asExtern(sourceMethod, args);
if (externApi.isPresent()) {
return callExtern(externApi.get(), args);
return callExtern(externApi.get(), args, node.getType());
}
return sourceFunctionCompiler.compile(node, sourceMethod, args, parameters, detacher);
}
Expand Down Expand Up @@ -2023,13 +2023,14 @@ SoyExpression visitPluginFunction(FunctionNode node) {
return callExtern(
ExternAdaptors.asExtern(
(SoyJavaExternFunction) fn, args, node.getType(), node.getAllowedParamTypes()),
args);
args,
node.getType());
} else if (fn instanceof SoyJavaSourceFunction) {
ImmutableList<SoyExpression> args = visitAllParams(node);
return sourceFunctionCompiler.compile(
node, (SoyJavaSourceFunction) fn, args, parameters, detacher);
} else if (fn instanceof Extern) {
return callExtern((Extern) fn, visitAllParams(node));
return callExtern((Extern) fn, visitAllParams(node), node.getType());
} else if (fn == FunctionNode.FUNCTION_POINTER) {
FunctionType functionType = node.getNameExpr().getType().asType(FunctionType.class);
SoyRuntimeType soyReturnType = ExternCompiler.getRuntimeType(functionType.getReturnType());
Expand Down Expand Up @@ -2107,7 +2108,8 @@ private ImmutableList<SoyExpression> visitAllParams(
return builder.build();
}

private SoyExpression callExtern(Extern extern, List<SoyExpression> params) {
private SoyExpression callExtern(
Extern extern, List<SoyExpression> params, SoyType resolvedReturnType) {
SourceLogicalPath path = extern.getPath();
JavaImpl javaImpl = extern.getJavaImpl();
boolean hasJavaImpl = javaImpl != null || extern.hasAutoImpl();
Expand All @@ -2125,7 +2127,7 @@ private SoyExpression callExtern(Extern extern, List<SoyExpression> params) {
linkStatically = hasJavaImpl && owningFile.getSoyFileKind() == SoyFileKind.SRC;
}
FunctionType functionType = extern.getSignature();
SoyRuntimeType soyReturnType = ExternCompiler.getRuntimeType(functionType.getReturnType());
SoyRuntimeType soyReturnType = ExternCompiler.getRuntimeType(resolvedReturnType);
boolean requiresRenderContext = !linkStatically || requiresRenderContext(extern);

if (extern.isJavaAsync()) {
Expand Down Expand Up @@ -2199,7 +2201,7 @@ private SoyExpression callExtern(Extern extern, List<SoyExpression> params) {
externCall =
ExternCompiler.adaptReturnType(
getTypeInfoForJavaImpl(javaImpl.returnType().className()).type(),
functionType.getReturnType(),
resolvedReturnType,
externCall);
// Allow ExternSourceFunction to return a boxed value.
if (isDefinitelyAssignableFrom(SOY_VALUE_TYPE, externCall.resultType())) {
Expand All @@ -2214,8 +2216,12 @@ private SoyExpression callExtern(Extern extern, List<SoyExpression> params) {
Method asmMethod =
ExternCompiler.buildMemberMethod(
extern.getName(), functionType, requiresRenderContext, extern.isJavaAsync());

Type descriptorReturnType = Type.getReturnType(asmMethod.getDescriptor());
Type expressionReturnType = soyReturnType.runtimeType();

externCall =
new Expression(soyReturnType.runtimeType()) {
new Expression(expressionReturnType) {
@Override
protected void doGen(CodeBuilder adapter) {
for (var arg : args) {
Expand All @@ -2227,6 +2233,39 @@ protected void doGen(CodeBuilder adapter) {
CALL_EXTERN_HANDLE,
externOwner.className(),
asmMethod.getName());

// Unbox if needed
if (!descriptorReturnType.equals(expressionReturnType)) {
if (expressionReturnType.equals(Type.LONG_TYPE)) {
adapter.visitMethodInsn(
Opcodes.INVOKEVIRTUAL,
"com/google/template/soy/data/SoyValue",
"longValue",
"()J",
false);
} else if (expressionReturnType.equals(Type.INT_TYPE)) {
adapter.visitMethodInsn(
Opcodes.INVOKEVIRTUAL,
"com/google/template/soy/data/SoyValue",
"integerValue",
"()I",
false);
} else if (expressionReturnType.equals(Type.DOUBLE_TYPE)) {
adapter.visitMethodInsn(
Opcodes.INVOKEVIRTUAL,
"com/google/template/soy/data/SoyValue",
"floatValue",
"()D",
false);
} else if (expressionReturnType.equals(Type.BOOLEAN_TYPE)) {
adapter.visitMethodInsn(
Opcodes.INVOKEVIRTUAL,
"com/google/template/soy/data/SoyValue",
"booleanValue",
"()Z",
false);
}
}
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@ protected void doGen(CodeBuilder cb) {
cb.ifZCmp(Opcodes.IFNE, end); // Stack: SVP, RR

saveOperation.gen(cb);
System.out.println("Jetski: BasicDetacher in method: " + cb.getThisMethodName());
if (cb.getReturnType().getSort() == org.objectweb.asm.Type.VOID) {
cb.pop(); // Pop RR
cb.pop(); // Pop SVP
}
cb.returnValue();
cb.mark(end);
cb.pop(); // Stack: SVP
Expand Down
32 changes: 16 additions & 16 deletions java/src/com/google/template/soy/jbcsrc/LazyClosureCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -497,24 +497,24 @@ private static ExpressionDetacher.BasicDetacher createOptimisticDetacher(
new Statement(Statement.Kind.TERMINAL) {
@Override
protected void doGen(CodeBuilder cb) {
cb.visitVarInsn(Opcodes.ILOAD, 0); // load the optimistic parameter
Label end = newLabel();
cb.ifZCmp(Opcodes.IFEQ, end); // if (optimistic) {
var methodParameters = cb.getArgumentTypes();
// Load all the arguments except the first one (the optimistic
// parameter)
var argTypes = copyOfRange(methodParameters, 1, methodParameters.length);
int index = Type.BOOLEAN_TYPE.getSize();
for (var argType : argTypes) {
cb.visitVarInsn(argType.getOpcode(Opcodes.ILOAD), index);
index += argType.getSize();
if (methodParameters.length > 0) {
cb.visitVarInsn(Opcodes.ILOAD, 0); // load the optimistic parameter
Label end = newLabel();
cb.ifZCmp(Opcodes.IFEQ, end); // if (optimistic) {
var argTypes = copyOfRange(methodParameters, 1, methodParameters.length);
int index = Type.BOOLEAN_TYPE.getSize();
for (var argType : argTypes) {
cb.visitVarInsn(argType.getOpcode(Opcodes.ILOAD), index);
index += argType.getSize();
}
cb.visitInvokeDynamicInsn(
cb.getThisMethodName(),
Type.getMethodDescriptor(providerSubclassType, argTypes),
bootstrapHandle);
cb.returnValue();
cb.mark(end);
}
cb.visitInvokeDynamicInsn(
cb.getThisMethodName(),
Type.getMethodDescriptor(providerSubclassType, argTypes),
bootstrapHandle);
cb.returnValue();
cb.mark(end);
}
};
return new ExpressionDetacher.BasicDetacher(Suppliers.ofInstance(optimisticDetacher));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ public Type[] getArgumentTypes() {
return adapter.getArgumentTypes();
}

public Type getReturnType() {
return adapter.getReturnType();
}

/** See {@link GeneratorAdapter#pop()} */
public void pop() {
adapter.pop();
Expand Down
Loading