Skip to content

Commit

Permalink
Add the print function built-in,
Browse files Browse the repository at this point in the history
Fixes wala#93.
  • Loading branch information
khatchad committed Oct 20, 2023
1 parent 1b1ffac commit f632d4b
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 0 deletions.
6 changes: 6 additions & 0 deletions com.ibm.wala.cast.python.test/data/print.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# From https://github.com/wala/ML/issues/93#issue-1953025479.
def f(x):
print("Traced with: " + str(x))


f(1)
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package com.ibm.wala.cast.python.test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access;
import com.ibm.wala.cast.ir.ssa.AstLexicalRead;
import com.ibm.wala.cast.python.client.PythonAnalysisEngine;
import com.ibm.wala.cast.python.ssa.PythonInvokeInstruction;
import com.ibm.wala.cast.python.types.PythonTypes;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
import com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder;
import com.ibm.wala.ipa.cha.ClassHierarchyException;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.intset.OrdinalSet;
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import org.junit.Test;

public class TestPrint extends TestPythonCallGraphShape {

private static final String PRINT_FUNCTION_VARIABLE_NAME = "print";

private static final TypeReference PRINT_FUNCTION_TYPE_REFERENCE =
TypeReference.findOrCreate(
PythonTypes.pythonLoader, "Lwala/builtin/" + PRINT_FUNCTION_VARIABLE_NAME);

@Test
public void testPrint()
throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
PythonAnalysisEngine<?> engine = makeEngine("print.py");
SSAPropagationCallGraphBuilder builder =
(SSAPropagationCallGraphBuilder) engine.defaultCallGraphBuilder();
CallGraph CG = builder.makeCallGraph(builder.getOptions());

Collection<CGNode> nodes = getNodes(CG, "script print.py/f");
assertEquals(1, nodes.size());

assertTrue(nodes.iterator().hasNext());
CGNode fNode = nodes.iterator().next();

IR fIR = fNode.getIR();

boolean foundPrintCall = false;
boolean foundBuiltIn = false;

for (Iterator<SSAInstruction> iit = fIR.iterateNormalInstructions(); iit.hasNext(); ) {
SSAInstruction instruction = iit.next();

if (instruction instanceof PythonInvokeInstruction) {
PythonInvokeInstruction invokeInstruction = (PythonInvokeInstruction) instruction;
int receiver = invokeInstruction.getReceiver();
assertTrue(receiver >= 0);

SSAInstruction receiverDefinition = fNode.getDU().getDef(receiver);

if (receiverDefinition instanceof AstLexicalRead) {
AstLexicalRead read = (AstLexicalRead) receiverDefinition;

assertEquals(1, read.getAccessCount());
Access access = read.getAccess(0);

if (access.variableName.equals(PRINT_FUNCTION_VARIABLE_NAME)) {
foundPrintCall = true;

// Found the print call. Let's ensure that it "points" to the built-in function.
PointerKey pk =
builder
.getPointerAnalysis()
.getHeapModel()
.getPointerKeyForLocal(fNode, access.valueNumber);
OrdinalSet<InstanceKey> pointsToSet = builder.getPointerAnalysis().getPointsToSet(pk);

for (Iterator<InstanceKey> pit = pointsToSet.iterator(); pit.hasNext(); ) {
InstanceKey ik = pit.next();

IClass concreteType = ik.getConcreteType();
TypeReference typeReference = concreteType.getReference();

if (typeReference.equals(PRINT_FUNCTION_TYPE_REFERENCE)) {
// found the built-in function in the pointer analysis.
foundBuiltIn = true;
break;
}
}
}
}
}
}

assertTrue(foundPrintCall && foundBuiltIn);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ private static TypeReference builtinFunction(String name) {
builtinFunctions.put("zip", Either.forLeft(PythonTypes.list));
builtinFunctions.put("slice", Either.forRight(2));
builtinFunctions.put("__delete__", Either.forRight(2));
// https://docs.python.org/3/library/functions.html#print
builtinFunctions.put("print", Either.forLeft(TypeReference.Void));
}

public static Set<String> builtins() {
Expand Down

0 comments on commit f632d4b

Please sign in to comment.