Commit b909e059 authored by Carlos Galindo's avatar Carlos Galindo
Browse files

Benchmarks for JSS Revision 1 (erlsom)

- Basic support for records, bin, float, try, catch
- Feature to count access constraints traversed
- Feature to count access constraints present in the graph
- Bugs fixed:
  - Can handle empty string represented as list `[]`.
  - Can handle other unary operators apart from `-int`.
  - Can handle nested list comprehensions.
- Now requires a running instance of erlang, use the following command:

    erl -pa (pwd)/e-Knife/src/main/resources -name server@localhost -setcookie erlang -noshell

- BencherTest now accepts `-DiterGen=NUM` and `-DiterSlice=NUM` as Java arguments.
parent 5a733894
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@ import edg.graph.LAST;
public class EDGFactory {
	private final LAST last;
	private EDG edg;
	private boolean interproceduralGraph = true; // CHANGE THIS ONE TO TRUE IN SETB
	private boolean interproceduralGraph = false; // CHANGE THIS ONE TO TRUE IN SETB
	private boolean summarisedGraph = false;

	public EDGFactory(LAST last)
+83 −1
Original line number Diff line number Diff line
@@ -279,6 +279,73 @@ public class LASTBuilder {
		return _throw.getId();
	}

	public static int addCatch(LAST last, int parentId, Where where, LDASTNodeInfo info) {
		Node parent = LASTBuilder.getParentNode(last, parentId, where);
		Node _catch = LASTBuilder.addNode(last, parent, Node.Type.Catch, "catch", info);
		return _catch.getId();
	}

	public static int addBin(LAST last, int parentId, Where where, LDASTNodeInfo info) {
		Node parent = LASTBuilder.getParentNode(last, parentId, where);
		Node node = LASTBuilder.addNode(last, parent, Node.Type.Bin, "bin", info);
		return node.getId();
	}

	public static int addBinElement(LAST last, int parentId, Where where, LDASTNodeInfo info) {
		Node parent = LASTBuilder.getParentNode(last, parentId, where);
		Node node = LASTBuilder.addNode(last, parent, Node.Type.Bin, "bin_element", info);
		return node.getId();
	}

	public static int addMap(LAST last, int parentId, Where where, LDASTNodeInfo info) {
		Node parent = LASTBuilder.getParentNode(last, parentId, where);
		Node node = LASTBuilder.addNode(last, parent, Node.Type.Map, "map", info);
		return node.getId();
	}

	public static int addMapFieldAssoc(LAST last, int parentId, Where where, LDASTNodeInfo info) {
		Node parent = LASTBuilder.getParentNode(last, parentId, where);
		Node node = LASTBuilder.addNode(last, parent, Node.Type.MapFieldAssoc, "map_field_assoc", info);
		return node.getId();
	}

	public static int addMapFieldExact(LAST last, int parentId, Where where, LDASTNodeInfo info) {
		Node parent = LASTBuilder.getParentNode(last, parentId, where);
		Node node = LASTBuilder.addNode(last, parent, Node.Type.MapFieldExact, "map_field_exact", info);
		return node.getId();
	}

	public static int addRecord(LAST last, int parentId, Where where, LDASTNodeInfo info) {
		Node parent = LASTBuilder.getParentNode(last, parentId, where);
		Node node = LASTBuilder.addNode(last, parent, Node.Type.Record, "record", info);
		return node.getId();
	}

	public static int addRecordField(LAST last, int parentId, Where where, LDASTNodeInfo info) {
		Node parent = LASTBuilder.getParentNode(last, parentId, where);
		Node node = LASTBuilder.addNode(last, parent, Node.Type.RecordField, "record_field", info);
		return node.getId();
	}

	public static int addRecordIndex(LAST last, int parentId, Where where, LDASTNodeInfo info) {
		Node parent = LASTBuilder.getParentNode(last, parentId, where);
		Node node = LASTBuilder.addNode(last, parent, Node.Type.RecordIndex, "record_index", info);
		return node.getId();
	}

	public static int addTryCatch(LAST last, int parentId, Where where, LDASTNodeInfo info) {
		Node parent = LASTBuilder.getParentNode(last, parentId, where);
		Node.Type type = null;
		switch (info.getConstruction()) {
			case "try_catch": type = Node.Type.TryCatch; break;
			case "try_of":    type = Node.Type.TryOf;    break;
			default:
				throw new IllegalArgumentException("Invalid try structure");
		}
		Node node = LASTBuilder.addNode(last, parent, type, info.getConstruction(), info);
		return node.getId();
	}

	public static int addListComprehension(LAST last, int parentId, Where where, LDASTNodeInfo info)
	{
		final Node parent = LASTBuilder.getParentNode(last, parentId, where);
@@ -364,7 +431,7 @@ public class LASTBuilder {
		return _return.getId();
	}

	private static Node addNode(LAST last, Node parent, Node.Type type, String name, LDASTNodeInfo info)
	/*TODO changed by me*/static Node addNode(LAST last, Node parent, Node.Type type, String name, LDASTNodeInfo info)
	{
		return LASTBuilder.addNode(last, parent, type, name, name, info);
	}
@@ -954,6 +1021,13 @@ public class LASTBuilder {
			case ExHandler:
				return LASTBuilder.getExhandlerChildNode(last, parentNode, where);

			case Try:
				switch (where) {
					case Body:
					case Cases:
					case Guard:
						return parentNode;
				}
			case TypeCheck: // ADDED
			case TypeTransformation: // ADDED
			case Throw:
@@ -978,6 +1052,14 @@ public class LASTBuilder {
			case PolymorphicNode:
			case Variable:
			case Result:
			case Catch:
			case Bin:
			case Map:
			case MapFieldAssoc:
			case MapFieldExact:
			case Record:
			case RecordField:
			case RecordIndex:
				if (where == null)
					return parentNode;
			default:
+147 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.function.BiConsumer;


import edg.LASTBuilder.Where;
@@ -584,6 +585,146 @@ public abstract class LASTFactory
		this.branches.pop();
	}

	/** Processes a catch expression <code>catch exp</code>.
	 * @param exp The expression inside the catch expression.
	 *  @see Node.Type#Catch */
	protected void addCatch(Object exp, LDASTNodeInfo info) {
		final Branch parent = this.branches.peek();
		final int id = LASTBuilder.addCatch(this.last, parent.getNodeId(), parent.getWhere(), info);

		this.branches.push(new Branch(id, Node.Type.Catch, info));
		processElement(exp, 1, 1);
		this.branches.pop();
	}

	protected void addBin(Object exp, LDASTNodeInfo info) {
		final Branch parent = this.branches.peek();
		final int id = LASTBuilder.addBin(this.last, parent.getNodeId(), parent.getWhere(), info);

		this.branches.push(new Branch(id, Node.Type.Bin, info));
		processElement(exp, 1, 1);
		this.branches.pop();
	}

	protected void addBinElement(Object exp, LDASTNodeInfo info) {
		final Branch parent = this.branches.peek();
		final int id = LASTBuilder.addBinElement(this.last, parent.getNodeId(), parent.getWhere(), info);

		this.branches.push(new Branch(id, Node.Type.BinElement, info));
		processElement(exp, 1, 1);
		this.branches.pop();
	}

	protected void addMap(Object[] exp, LDASTNodeInfo info) {
		final Branch parent = this.branches.peek();
		final int id = LASTBuilder.addMap(this.last, parent.getNodeId(), parent.getWhere(), info);

		this.branches.push(new Branch(id, Node.Type.Map, info));
		processElements(exp);
		this.branches.pop();
	}

	protected void addMap(Object name, Object[] exp, LDASTNodeInfo info) {
		final Branch parent = this.branches.peek();
		final int id = LASTBuilder.addMap(this.last, parent.getNodeId(), parent.getWhere(), info);

		this.branches.push(new Branch(id, Node.Type.Map, info));
		processElement(name, 1, exp.length + 1);
		for (int i = 0; i < exp.length; i++)
			processElement(exp[i], i, exp.length + 1);
		this.branches.pop();
	}

	protected void addMapFieldAssoc(Object exp, LDASTNodeInfo info) {
		final Branch parent = this.branches.peek();
		final int id = LASTBuilder.addMapFieldAssoc(this.last, parent.getNodeId(), parent.getWhere(), info);

		this.branches.push(new Branch(id, Node.Type.MapFieldAssoc, info));
		processElement(exp, 1, 1);
		this.branches.pop();
	}

	protected void addMapFieldExact(Object exp1, Object exp2, LDASTNodeInfo info) {
		final Branch parent = this.branches.peek();
		final int id = LASTBuilder.addMapFieldExact(this.last, parent.getNodeId(), parent.getWhere(), info);

		this.branches.push(new Branch(id, Node.Type.MapFieldAssoc, info));
		processElement(exp1, 1, 2);
		processElement(exp2, 2, 2);
		this.branches.pop();
	}

	protected void addRecord(Object record, Object[] fields, LDASTNodeInfo info) {
		final Branch parent = this.branches.peek();
		final int id = LASTBuilder.addRecord(this.last, parent.getNodeId(), parent.getWhere(), info);

		this.branches.push(new Branch(id, Node.Type.Record, info));
		processElement(record, 1, fields.length + 1);
		for (int i = 0; i < fields.length; i++)
			processElement(fields[i], i + 1, fields.length + 1);
		this.branches.pop();
	}

	protected void addRecord(Object name, Object record, Object[] fields, LDASTNodeInfo info) {
		final Branch parent = this.branches.peek();
		final int id = LASTBuilder.addRecord(this.last, parent.getNodeId(), parent.getWhere(), info);

		this.branches.push(new Branch(id, Node.Type.Record, info));
		processElement(name, 1, fields.length + 2);
		processElement(record, 2, fields.length + 2);
		for (int i = 0; i < fields.length; i++)
			processElement(fields[i], i + 2, fields.length + 2);
		this.branches.pop();
	}

	protected void addRecordField(Object name, Object value, LDASTNodeInfo info) {
		final Branch parent = this.branches.peek();
		final int id = LASTBuilder.addRecordField(this.last, parent.getNodeId(), parent.getWhere(), info);

		this.branches.push(new Branch(id, Node.Type.RecordField, info));
		processElement(name, 1, 2);
		processElement(value, 2, 2);
		this.branches.pop();
	}

	protected void addRecordIndex(Object name, Object assign, LDASTNodeInfo info) {
		final int id = LASTBuilder.addRecordIndex(last, branches.peek().getNodeId(), branches.peek().getWhere(), info);

		branches.push(new Branch(id, Node.Type.RecordIndex, info));
		processElement(name, 1, 2);
		processElement(assign, 2, 2);
		branches.pop();
	}

	protected <T, R> void addTry(T[] tryBody, T[] tryClauses, R catchClauses, T[] afterBody,
							  LDASTNodeInfo info, LDASTNodeInfo tryInfo, LDASTNodeInfo catchInfo,
							  BiConsumer<Node, R> catchClauseHandler) {
		int id = LASTBuilder.addTryCatch(last, branches.peek().getNodeId(), branches.peek().getWhere(), info);
		Node node = last.getNode(id);

		branches.push(new Branch(node));

		Node tryNode = LASTBuilder.addNode(last, node, Node.Type.Try, "try", tryInfo);
		branches.push(new Branch(tryNode));
		branches.peek().setWhere(Where.Body);
		processElements(tryBody);
		branches.peek().setWhere(Where.Cases);
		processElements(tryClauses);
		branches.pop();

		Node catchNode = LASTBuilder.addNode(last, node, Node.Type.Catch, "catch", catchInfo);
		branches.push(new Branch(catchNode));
		catchClauseHandler.accept(catchNode, catchClauses);
		branches.pop();

		Node afterNode = LASTBuilder.addNode(last, node, Node.Type.AfterTry, "after_try", info);
		branches.push(new Branch(afterNode));
		processElements(afterBody);
		branches.pop();

		branches.pop();
	}

	// LOOPS
	protected <R, S, T> void addForLoop(Iterable<T> initialization, R condition, Iterable<S> bodyExpressions, Iterable<T> update, LDASTNodeInfo info)
	{
@@ -749,6 +890,8 @@ public abstract class LASTFactory
		
		branch.setWhere(Where.Parameters);
		this.processElement(parameter,1,1);
		branch.setWhere(Where.Guard);
		this.processElement(guard, 1, 1);
		branch.setWhere(Where.Body);
		this.processElements(catchBlock);
		this.branches.pop();
@@ -861,6 +1004,10 @@ public abstract class LASTFactory
			this.ldNodeInfo = ldNodeInfo;
		}

		public Branch(Node node) {
			this(node.getId(), node.getType(), node.getInfo());
		}

		public int getNodeId()
		{
			return this.nodeId;
+4 −1
Original line number Diff line number Diff line
@@ -73,6 +73,9 @@ public class ListComprehensionConstraint extends AccessConstraint {
	{
		if (topConstraint.operation == Operation.Add && this.cancels(topConstraint))
			return super.wrap(super.pop(constraints));
		// added for ejabberd
		// TODO we never considered that a list comprehension could be inside another list comprehension
		if (this.operation != Operation.Add)
			super.check(phase, Phase.SummaryGeneration);
		return super.wrap(super.push(phase, constraints));
	}
+35 −2
Original line number Diff line number Diff line
package edg.graph;

import com.sun.source.tree.Scope;
import edg.LDASTNodeInfo;
import edg.visitor.GenericVisitor;
import edg.visitor.Visitable;
import edg.visitor.VoidVisitor;

import java.beans.Expression;
import java.util.Objects;

public class Node implements Visitable {
@@ -28,6 +26,17 @@ public class Node implements Visitable {
		CLoop, FLoop, RLoop, Foreach, Iterator, // LOOPS
		ExHandler, Try, Catch, Finally, CatchClause, Throw, // EXCEPTIONS

		// Elements added for ejabberd
		Bin, // binary representation of data
		BinElement, // Elements within Bin
		Map, // A map declaration or access
		MapFieldAssoc, // Associate fields in a Map
		MapFieldExact, // something else to do with maps
		Record, RecordField, RecordIndex,
		TryCatch, // Erlangggg
		TryOf, // MMore erlang
		AfterTry, // etc

		// Others
		Body(true), Guard(true),
		Expression(true), Result(false, true),
@@ -455,6 +464,30 @@ public class Node implements Visitable {
			case Index:
				visitor.visitIndex(this, argument);
				break;
			case Bin:
				visitor.visitBin(this, argument);
				break;
			case BinElement:
				visitor.visitBinElement(this, argument);
				break;
			case Record:
				visitor.visitRecord(this, argument);
				break;
			case RecordField:
				visitor.visitRecordField(this, argument);
				break;
			case RecordIndex:
				visitor.visitRecordIndex(this, argument);
				break;
			case TryCatch:
				visitor.visitTryCatch(this, argument);
				break;
			case TryOf:
				visitor.visitTryOf(this, argument);
				break;
			case AfterTry:
				visitor.visitAfterTry(this, argument);
				break;
			default:
				throw new IllegalStateException("Type cannot be visited: " + type);
		}
Loading