Skip to content

Commit 37d685d

Browse files
committed
Bytecode DSL fix: last expr statement in module is return value for interop eval even if it is a docstring
1 parent 4a0e3ce commit 37d685d

File tree

2 files changed

+32
-27
lines changed
  • graalpython
    • com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/basic
    • com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl

2 files changed

+32
-27
lines changed

graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/basic/HelloWorldTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232

3333
import org.graalvm.polyglot.Context;
3434
import org.graalvm.polyglot.Engine;
35+
import org.graalvm.polyglot.Value;
36+
import org.junit.Assert;
3537
import org.junit.Test;
3638

3739
import com.oracle.graal.python.test.integration.PythonTests;
@@ -50,6 +52,12 @@ public void helloworldAgain() {
5052
PythonTests.assertPrints("hello\n", source);
5153
}
5254

55+
@Test
56+
public void helloworldExpression() {
57+
Value value = PythonTests.eval("'hello world'");
58+
Assert.assertEquals("hello world", value.asString());
59+
}
60+
5361
@Test
5462
public void usesFrozenModules() {
5563
final ByteArrayOutputStream byteArray = new ByteArrayOutputStream();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/RootNodeCompiler.java

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ String maybeMangleAndAddName(String name) {
765765
public BytecodeDSLCompilerResult visit(ModTy.Module node) {
766766
return compileRootNode("<module>", ArgumentInfo.NO_ARGS, node.getSourceRange(), b -> {
767767
beginRootNode(node, null, b);
768-
visitModuleBody(node.body, b);
768+
visitModuleBody(node.body, b, true);
769769
endRootNode(b);
770770
});
771771
}
@@ -785,12 +785,12 @@ public BytecodeDSLCompilerResult visit(ModTy.Expression node) {
785785
public BytecodeDSLCompilerResult visit(ModTy.Interactive node) {
786786
return compileRootNode("<module>", ArgumentInfo.NO_ARGS, node.getSourceRange(), b -> {
787787
beginRootNode(node, null, b);
788-
visitModuleBody(node.body, b);
788+
visitModuleBody(node.body, b, false);
789789
endRootNode(b);
790790
});
791791
}
792792

793-
private void visitModuleBody(StmtTy[] body, Builder b) {
793+
private void visitModuleBody(StmtTy[] body, Builder b, boolean returnLastStmt) {
794794
if (body != null) {
795795
if (containsAnnotations(body)) {
796796
b.emitSetupAnnotations();
@@ -827,33 +827,30 @@ private void visitModuleBody(StmtTy[] body, Builder b) {
827827
endStoreLocal("__doc__", b);
828828
}
829829
}
830-
if (i == body.length) {
831-
// Special case: module body just consists of a docstring.
830+
831+
for (; i < body.length - 1; i++) {
832+
body[i].accept(statementCompiler);
833+
}
834+
835+
/*
836+
* To support interop eval we need to return the value of the last statement even if
837+
* we're in file mode. Also used when parsing with arguments. Note that if there is
838+
* only a doc string, although we normally skip it, here we use it as a return
839+
* value.
840+
*/
841+
StmtTy lastStatement = body[body.length - 1];
842+
if (returnLastStmt && lastStatement instanceof StmtTy.Expr expr) {
843+
// Return the value of the last statement for interop eval.
844+
beginReturn(b);
845+
boolean closeTag = beginSourceSection(expr, b);
846+
expr.value.accept(statementCompiler);
847+
endSourceSection(b, closeTag);
848+
endReturn(b);
849+
} else {
850+
lastStatement.accept(statementCompiler);
832851
beginReturn(b);
833852
b.emitLoadConstant(PNone.NONE);
834853
endReturn(b);
835-
return;
836-
}
837-
838-
for (; i < body.length; i++) {
839-
StmtTy bodyNode = body[i];
840-
if (i == body.length - 1) {
841-
if (bodyNode instanceof StmtTy.Expr expr) {
842-
// Return the value of the last statement for interop eval.
843-
beginReturn(b);
844-
boolean closeTag = beginSourceSection(expr, b);
845-
expr.value.accept(statementCompiler);
846-
endSourceSection(b, closeTag);
847-
endReturn(b);
848-
} else {
849-
bodyNode.accept(statementCompiler);
850-
beginReturn(b);
851-
b.emitLoadConstant(PNone.NONE);
852-
endReturn(b);
853-
}
854-
} else {
855-
bodyNode.accept(statementCompiler);
856-
}
857854
}
858855
}
859856
} else {

0 commit comments

Comments
 (0)