import edu.uci.eecs.codeGenerator.CodeAdditions.CodeAddition;
import edu.uci.eecs.specExtraction.Code;
import edu.uci.eecs.specExtraction.Construct;
+import edu.uci.eecs.specExtraction.DefineConstruct;
import edu.uci.eecs.specExtraction.EntryConstruct;
import edu.uci.eecs.specExtraction.InterfaceConstruct;
import edu.uci.eecs.specExtraction.OPConstruct;
// Extract all the additions
ArrayList<OPConstruct> OPList = extractor.OPListMap.get(file);
EntryConstruct entry = extractor.entryMap.get(file);
+ ArrayList<DefineConstruct> defineList = extractor.defineListMap
+ .get(file);
ArrayList<InterfaceConstruct> interfaceList = extractor.interfaceListMap
.get(file);
Code code = null;
addition = new CodeAddition(entry.beginLineNum, code);
additions.addCodeAddition(addition);
}
+ // For define constructs
+ if (defineList != null) {
+ for (DefineConstruct con : defineList) {
+ code = CodeGeneratorUtils.Generate4Define(con);
+ addition = new CodeAddition(con.endLineNum,
+ code);
+ additions.addCodeAddition(addition);
+ }
+ }
// For interface constructs
if (interfaceList != null) {
for (InterfaceConstruct con : interfaceList) {
}
static public void main(String[] args) {
- String[] dirNames = { Environment.REGISTER, Environment.MS_QUEUE, Environment.LINUXRWLOCKS, Environment.MCS_LOCK, Environment.DEQUE };
+ String[] dirNames = { Environment.REGISTER, Environment.MS_QUEUE,
+ Environment.LINUXRWLOCKS, Environment.MCS_LOCK,
+ Environment.DEQUE };
for (int i = 0; i < dirNames.length; i++) {
String dirName = dirNames[i];
import edu.uci.eecs.specExtraction.Code;
import edu.uci.eecs.specExtraction.CommutativityRule;
+import edu.uci.eecs.specExtraction.DefineConstruct;
import edu.uci.eecs.specExtraction.EntryConstruct;
import edu.uci.eecs.specExtraction.FunctionHeader;
import edu.uci.eecs.specExtraction.GlobalConstruct;
'_') + "_H");
code.addLine("");
+ // FIXME: We have included ad-hoc header files here
// System included headers
code.addLine(ShortComment("System included headers go here"));
- for (String header : SpecNaming.includedHeadersList) {
- code.addLine(IncludeHeader(header));
- }
+ code.addLine(IncludeHeader(SpecNaming.SPECANNOTATION_API));
+ code.addLine(IncludeHeader(SpecNaming.STDLIB));
+
code.addLine("");
// Users included headers
- // FIXME: We don't add user-defined headers, but as a workaround we only add forward class.
code.addLine(ShortComment("User included headers go here"));
for (String header : headerFiles) {
code.addLine(IncludeHeader(header));
}
code.addLine("");
-
-// code.addLine(ShortComment("Forward declaration goes here"));
-// for (String type : extractor.forwardClass) {
-// code.addLine("class " + type + ";");
-// }
-// code.addLine("");
-
- code.addLine("using namespace std;");
- code.addLine("");
+
+ // Decalre extern "C" --- begin
+ code.addLine("#ifdef __cplusplus");
+ code.addLine("extern \"C\" {");
+ code.addLine("#endif");
code.addLine("");
code.addLine(ShortComment("Declaration of some c-strings (CSTR)"));
}
}
- // Declare customized StateStruct
- code.addLine(ShortComment("Declare customized StateStruct"));
- code.addLine("typedef struct " + SpecNaming.StateStruct + " {");
- for (VariableDeclaration decl : globalConstruct.declState) {
- code.addLine(TabbedLine(Declare(decl)));
- }
- code.addLine("");
- code.addLine(TabbedLine("SNAPSHOTALLOC"));
- code.addLine("} " + SpecNaming.StateStruct + ";");
- code.addLine("");
-
// Declare customized value struct
for (File file : interfaceListMap.keySet()) {
ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
code.addLine(ShortComment("Declare INIT annotation instrumentation function"));
code.addLine("void _createInitAnnotation();");
code.addLine("");
+
+ // Decalre extern "C" --- begin
+ code.addLine("#ifdef __cplusplus");
+ code.addLine("};");
+ code.addLine("#endif");
+ code.addLine("");
+
+ // Declare #endif
code.addLine("#endif");
return code;
code.addLine("");
code.addLine("#include " + SpecNaming.CDSSpecGeneratedHeader);
+ code.addLine("#include " + SpecNaming.CDSANNOTATE);
+ code.addLine("#include " + SpecNaming.SPEC_COMMON);
+ code.addLine("#include " + SpecNaming.METHODCALL);
+ code.addLine("#include " + SpecNaming.CDSSPEC);
+ code.addLine("#include " + SpecNaming.SPECANNOTATION);
+ code.addLine("");
+ code.addLine("");
+
+ // Declare customized StateStruct
+ code.addLine(ShortComment("Declare customized StateStruct"));
+ code.addLine("typedef struct " + SpecNaming.StateStruct + " {");
+ for (VariableDeclaration decl : globalConstruct.declState) {
+ code.addLine(TabbedLine(Declare(decl)));
+ }
+ code.addLine("");
+ code.addLine(TabbedLine("SNAPSHOTALLOC"));
+ code.addLine("} " + SpecNaming.StateStruct + ";");
code.addLine("");
code.addLine("");
return res;
}
+ /**
+ * <p>
+ * This function generates the code to be inserted right after the "@Define"
+ * construct (instrumentation code)
+ * </p>
+ *
+ * @param construct
+ * The corresponding entry construct
+ * @return
+ */
+ public static Code Generate4Define(DefineConstruct construct) {
+ Code code = new Code();
+ code.addLine("");
+ code.addLine("/********** User-defined code in annotation (BEGIN) **********/");
+ code.addLines(construct.code);
+ code.addLine("/********** User-defined code in annotation (END) **********/");
+ return code;
+ }
+
/**
* <p>
* This function generates the new interface wrapper code to be inserted
} else {
code.addLine(beginLine);
}
- // Instrument with the INTERFACE_BEGIN annotation
+ // Instrument with the INTERFACE_BEGIN annotations
code.addLine(prefixTabs
+ "\t"
+ ShortComment("Instrument with the INTERFACE_BEGIN annotation"));
- // AnnoInterfaceInfo *info = _createInterfaceBeginAnnotation(_DEQ_str);
+ // CAnnoInterfaceInfo info = _createInterfaceBeginAnnotation(_DEQ_str);
code.addLine(prefixTabs
+ "\t"
+ DeclareDefine(SpecNaming.AnnoInterfaceInfo, "*"
+ ShortComment("Initialize the value struct"));
// The very first assignment "
code.addLine(prefixTabs + "\t"
- + DeclareDefine(name, "*value", "new " + name));
+ + DeclareDefine(name, "*value", SpecNaming.New + Brace(name)));
// Don't leave out the RET field
if (!construct.getFunctionHeader().isReturnVoid())
code.addLine(prefixTabs + "\t"
code.addLine("");
// Store the value info into the current MethodCall
+ // _setInterfaceBeginAnnotationValue(info, value);
code.addLine(prefixTabs
+ "\t"
+ ShortComment("Store the value info into the current MethodCall"));
- code.addLine(prefixTabs
- + "\t"
- + AssignToPtr(SpecNaming.AnnoInterfaceInfoInst, "value",
- "value"));
+ code.addLine(prefixTabs + "\t"
+ + SpecNaming.SetInterfaceBeginAnnoValueFunc
+ + Brace(SpecNaming.AnnoInterfaceInfoInst + ", value") + ";");
code.addLine("");
// Return if necessary
--- /dev/null
+package edu.uci.eecs.specExtraction;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import edu.uci.eecs.specExtraction.SpecUtils.IntObj;
+import edu.uci.eecs.specExtraction.SpecUtils.Primitive;
+import edu.uci.eecs.utilParser.ParseException;
+import edu.uci.eecs.utilParser.UtilParser;
+
+/**
+ * <p>
+ * This class is a subclass of Construct. It represents user-defined code that
+ * we allow in the header file. Note that the code here basically are the same
+ * as writing code right in place. We require function declaration/definition to
+ * be inline. Users should be responsible for the correctness of their code.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class DefineConstruct extends Construct {
+ public final Code code;
+
+ // The ending line number of the specification annotation construct
+ public final int endLineNum;
+
+ public DefineConstruct(File file, int beginLineNum, int endLineNum,
+ ArrayList<String> annotations) throws WrongAnnotationException {
+ super(file, beginLineNum);
+ code = new Code();
+ this.endLineNum = endLineNum;
+ Primitive define = SpecUtils.extractPrimitive(file, beginLineNum,
+ annotations, new IntObj(0));
+ code.addLines(define.contents);
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(super.toString() + "\n");
+ sb.append("@Define:\n");
+ if (!code.isEmpty()) {
+ sb.append(code);
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+}
*
*/
public class SpecExtractor {
+ public final HashMap<File, ArrayList<DefineConstruct>> defineListMap;
public final HashMap<File, ArrayList<InterfaceConstruct>> interfaceListMap;
public final HashMap<File, ArrayList<OPConstruct>> OPListMap;
public final HashSet<String> OPLabelSet;
private GlobalConstruct globalConstruct;
public SpecExtractor() {
+ defineListMap = new HashMap<File, ArrayList<DefineConstruct>>();
interfaceListMap = new HashMap<File, ArrayList<InterfaceConstruct>>();
OPListMap = new HashMap<File, ArrayList<OPConstruct>>();
OPLabelSet = new HashSet<String>();
forwardClass = new HashSet<String>();
globalConstruct = null;
}
+
+ private void addDefineConstruct(DefineConstruct construct) {
+ ArrayList<DefineConstruct> list = defineListMap
+ .get(construct.file);
+ if (list == null) {
+ list = new ArrayList<DefineConstruct>();
+ defineListMap.put(construct.file, list);
+ }
+ list.add(construct);
+ }
private void addInterfaceConstruct(InterfaceConstruct construct) {
ArrayList<InterfaceConstruct> list = interfaceListMap
// -1 means the curl symbols in the interface do not match
return -1;
}
+
+ /**
+ * <p>
+ * A sub-routine to extract the define construct. When called, we have
+ * already match the beginning of the construct, and we also need to find
+ * the ending line number of the anntotation.
+ * </p>
+ *
+ * @param file
+ * The file that we are processing
+ * @param lineReader
+ * The LineNumberReader that we are using when processing the
+ * current file.
+ * @param curLine
+ * The current line that we are processing. It should be the
+ * beginning line of the annotation construct.
+ * @param beginLineNum
+ * The beginning line number of the interface construct
+ * annotation
+ * @throws WrongAnnotationException
+ * @throws IOException
+ * @throws ParseException
+ */
+ private void extractDefineConstruct(File file,
+ LineNumberReader lineReader, String curLine, int beginLineNum)
+ throws WrongAnnotationException, IOException, ParseException {
+ ArrayList<String> annotations = extractTillConstructEnd(file,
+ lineReader, curLine, beginLineNum);
+ int endLineNum = lineReader.getLineNumber();
+ DefineConstruct construct = new DefineConstruct(file,
+ beginLineNum, endLineNum, annotations);
+ addDefineConstruct(construct);
+ }
+
/**
* <p>
lineReader = new LineNumberReader(br);
// "/\*\*\s*@(DeclareState|Interface)"
Pattern regexpBegin = Pattern
- .compile("/\\*\\*\\s*@(DeclareState|Interface)");
+ .compile("/\\*\\*\\s*@(DeclareState|Interface|Define)");
Matcher matcher = regexpBegin.matcher("");
String line;
} else if (constructName.equals(SpecNaming.Interface)) {
extractInterfaceConstruct(file, lineReader, line,
beginLineNum);
+ } else if (constructName.equals(SpecNaming.Define)) {
+ extractDefineConstruct(file, lineReader, line,
+ beginLineNum);
} else {
WrongAnnotationException.err(file, beginLineNum,
constructName
public static final String FinalState = "Final";
public static final String PrintState = "Print";
public static final String Commutativity = "Commutativity";
+
+ // Define construct
+ public static final String Define = "Define";
// Interface construct
public static final String Interface = "Interface";
public static final String MODELASSERT = "\"model-assert.h\"";
public static final String LIBRACE = "\"librace.h\"";
public static final String SPECANNOTATION = "\"specannotation.h\"";
- public static final String SPECCOMMON = "\"spec_common.h\"";
+ public static final String SPEC_COMMON = "\"spec_common.h\"";
public static final String CDSSPEC = "\"cdsspec.h\"";
public static final String METHODCALL = "\"methodcall.h\"";
+
+ // Header files to include in the cdsspec-generated.h
+ public static final String SPECANNOTATION_API = "\"specannotation-api.h\"";
+
+ // Header files to include in the cdsspec-generated.cc
+ // <cdsannotate.h>
+ // "spec_common.h"
+ // "methodcall.h"
+ // "cdsspec.h"
+ // "specannotation.h"
static {
// Initialize the header set and list
includedHeadersList.add(MODELASSERT);
includedHeadersList.add(LIBRACE);
includedHeadersList.add(SPECANNOTATION);
- includedHeadersList.add(SPECCOMMON);
+ includedHeadersList.add(SPEC_COMMON);
includedHeadersList.add(METHODCALL);
includedHeadersList.add(CDSSPEC);
// Some CDSSpec keywords and function names
public static final String NewSize = "NEW_SIZE";
+ public static final String New = "NEW";
// Some CDSSpec types
public static final String CString = "CSTR";
public static final String EmptyCString = "_EMPTY";
public static final String AnnoInit = "AnnoInit";
public static final String AnnoTypeInit = "INIT";
public static final String AnnoInterfaceInfo = "AnnoInterfaceInfo";
+ public static final String CAnnoInterfaceInfo = "CAnnoInterfaceInfo";
public static final String SpecAnnotation = "SpecAnnotation";
// Some CDSSpec state functions
// Functions for instrumenting annotation
public static final String CreateInitAnnoFunc = "_createInitAnnotation";
public static final String CreateInterfaceBeginAnnoFunc = "_createInterfaceBeginAnnotation";
+ public static final String SetInterfaceBeginAnnoValueFunc = "_setInterfaceBeginAnnotationValue";
public static final String CreateOPDefineAnnoFunc = "_createOPDefineAnnotation";
public static final String CreatePotentialOPAnnoFunc = "_createPotentialOPAnnotation";
public static final String CreateOPCheckAnnoFunc = "_createOPCheckAnnotation";