1 package edu.uci.eecs.specCompiler.codeGenerator;
3 import java.util.ArrayList;
4 import java.util.HashSet;
7 import edu.uci.eecs.specCompiler.grammerParser.ParseException;
8 import edu.uci.eecs.specCompiler.grammerParser.SpecParser;
9 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
10 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
11 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
12 import edu.uci.eecs.specCompiler.specExtraction.Construct;
13 import edu.uci.eecs.specCompiler.specExtraction.FunctionHeader;
14 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
15 import edu.uci.eecs.specCompiler.specExtraction.IDExtractor;
16 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
17 import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
18 import edu.uci.eecs.specCompiler.specExtraction.ParserUtils;
19 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
20 import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
21 import edu.uci.eecs.specCompiler.specExtraction.SpecExtractor;
22 import edu.uci.eecs.specCompiler.specExtraction.VariableDeclaration;
24 public class CodeVariables {
25 // C++ code or library
26 public static final String HEADER_STDLIB = "<stdlib.h>";
27 public static final String HEADER_THREADS = "<threads.h>";
28 public static final String HEADER_STDINT = "<stdint.h>";
29 public static final String ThreadIDType = "thrd_t";
30 public static final String GET_THREAD_ID = "thrd_current";
31 public static final String BOOLEAN = "bool";
32 public static final String UINT64 = "uint64_t";
35 public static final String HEADER_CDSANNOTATE = "<cdsannotate.h>";
36 public static final String HEADER_COMMON = "<common.h>";
37 public static final String HEADER_SPECANNOTATION = "<specannotation.h>";
38 public static final String HEADER_CDSTRACE = "<cdstrace.h>";
39 // public static final String CDSAnnotate = "cdsannotate";
40 public static final String CDSAnnotate = "_Z11cdsannotatemPv";
41 public static final String CDSAnnotateType = "SPEC_ANALYSIS";
42 public static final String IDType = "call_id_t";
44 public static final String SPEC_ANNO_TYPE = "spec_anno_type";
45 public static final String SPEC_ANNO_TYPE_FUNC_TABLE_INIT = "FUNC_TABLE_INIT";
46 public static final String SPEC_ANNO_TYPE_HB_INIT = "HB_INIT";
47 public static final String SPEC_ANNO_TYPE_INTERFACE_BEGIN = "INTERFACE_BEGIN";
48 public static final String SPEC_ANNO_TYPE_HB_CONDITION = "HB_CONDITION";
49 public static final String SPEC_ANNO_TYPE_INTERFACE_END = "INTERFACE_END";
50 public static final String SPEC_ANNO_TYPE_POTENTIAL_CP_DEFINE = "POTENTIAL_CP_DEFINE";
51 public static final String SPEC_ANNO_TYPE_CP_DEFINE_CHECK = "CP_DEFINE_CHECK";
52 public static final String SPEC_ANNO_TYPE_CP_DEFINE = "CP_DEFINE";
53 public static final String SPEC_ANNOTATION = "spec_annotation";
54 public static final String SPEC_ANNOTATION_FIELD_TYPE = "type";
55 public static final String SPEC_ANNOTATION_FIELD_ANNO = "annotation";
57 public static final String ANNO_FUNC_TABLE_INIT = "anno_func_table_init";
58 public static final String ANNO_HB_INIT = "anno_hb_init";
59 public static final String ANNO_INTERFACE_BEGIN = "anno_interface_begin";
60 public static final String ANNO_INTERFACE_END = "anno_interface_end";
61 public static final String ANNO_POTENTIAL_CP_DEFINE = "anno_potentail_cp_define";
62 public static final String ANNO_CP_DEFINE = "anno_cp_define";
63 public static final String ANNO_CP_DEFINE_CHECK = "anno_cp_define_check";
64 public static final String ANNO_HB_CONDITION = "anno_hb_condition";
66 // Specification variables
67 public static final String SPEC_INTERFACE_WRAPPER = "__wrapper_";
68 public static final String DEFAULT_ID = "0";
70 // Specification library
71 public static final String HEADER_SPEC_LIB = "<spec_lib.h>";
72 public static final String SPEC_QUEUE = "spec_queue";
73 public static final String SPEC_STACK = "spec_stack";
74 public static final String SPEC_DEQUE = "spec_deque";
75 public static final String SPEC_HASHTABLE = "spec_hashtable";
76 public static final String SPEC_PRIVATE_HASHTABLE = "spec_private_hashtable";
77 public static final String SPEC_TAG = "spec_tag";
78 public static final String SPEC_TAG_CURRENT = "current";
79 public static final String SPEC_TAG_NEXT = "next";
82 public static final String MACRO_ID = "__ID__";
83 public static final String MACRO_COND = "__COND_SAT__";
84 public static final String MACRO_RETURN = "__RET__";
85 public static final String MACRO_ATOMIC_RETURN = "__ATOMIC_RET__";
87 public static void printCode(ArrayList<String> code) {
88 for (int i = 0; i < code.size(); i++) {
89 System.out.println(code.get(i));
93 private static String COMMENT(String comment) {
94 return "/* " + comment + " */";
97 private static String INCLUDE(String header) {
98 return "#include " + header;
101 private static String DEFINE(String left, String right) {
102 return "#define " + left + " " + right;
105 private static String UNDEFINE(String macro) {
106 return "#undef " + macro;
109 private static String GET_FIELD_BY_PTR(String ptr, String field) {
110 return ptr + "->" + field;
113 private static String GET_FIELD(String var, String field) {
114 return var + "->" + field;
117 private static String BRACE(String val) {
118 return "(" + val + ")";
121 private static String ASSIGN(String structName, String field, String val) {
122 return structName + "." + field + " = " + val + ";";
125 private static String ASSIGN(String varName, String val) {
126 return varName + " = " + val + ";";
129 private static String ASSIGN_PTR(String structName, String field, String val) {
130 return structName + "." + field + " = &" + val + ";";
133 private static String ASSIGN_TO_PTR(String structName, String field,
135 return structName + "->" + field + " = " + val + ";";
138 private static String ASSIGN_PTR_TO_PTR(String structName, String field,
140 return structName + "->" + field + " = &" + val + ";";
143 private static String STRUCT_NEW_DECLARE_DEFINE(String type, String name) {
144 return "struct " + type + " *" + name + " = (struct " + type
145 + "*) malloc(sizeof(struct " + type + "));";
148 private static String DECLARE(String type, String name) {
149 return type + " " + name + ";";
152 private static String DECLARE(VariableDeclaration varDecl) {
153 String type = varDecl.type, name = varDecl.name;
154 return type + " " + name + ";";
157 private static String DECLARE_DEFINE(String type, String var, String val) {
158 return type + " " + var + " = " + val + ";";
161 private static String ANNOTATE(String structName) {
162 return CDSAnnotate + "(" + CDSAnnotateType + ", " + structName + ");";
165 private static ArrayList<String> DEFINE_INFO_STRUCT(String interfaceName,
166 FunctionHeader header) {
167 ArrayList<String> code = new ArrayList<String>();
168 code.add("typedef struct " + interfaceName + "_info {");
169 if (!header.returnType.equals("void")) {
170 code.add(DECLARE(header.returnType, MACRO_RETURN));
172 for (int i = 0; i < header.args.size(); i++) {
173 code.add(DECLARE(header.args.get(i)));
175 code.add("} " + interfaceName + "_info;");
179 private static ArrayList<String> DEFINE_ID_FUNC(String interfaceName,
181 ArrayList<String> code = new ArrayList<String>();
182 code.add("inline static " + IDType + " " + interfaceName + "_id() {");
183 if (!idCode.equals("")) {
184 code.add(DECLARE_DEFINE(IDType, MACRO_ID, idCode));
186 code.add(DECLARE_DEFINE(IDType, MACRO_ID, DEFAULT_ID));
188 code.add("return " + MACRO_ID + ";");
193 private static ArrayList<String> DEFINE_CHECK_ACTION_FUNC(
194 InterfaceConstruct construct, FunctionHeader header) {
195 String interfaceName = construct.name;
196 ArrayList<String> code = new ArrayList<String>();
197 code.add("inline static bool " + interfaceName + "_check_action(void *info, "
198 + IDType + " " + MACRO_ID + ") {");
199 code.add(DECLARE("bool", "check_passed"));
201 if (!header.returnType.equals("void") || header.args.size() != 0) {
202 String infoStructType = interfaceName + "_info", infoStructName = "theInfo";
203 code.add(DECLARE_DEFINE(infoStructType + "*", infoStructName,
204 BRACE(infoStructType + "*") + "info"));
205 if (!header.returnType.equals("void")) {
206 code.add((DECLARE_DEFINE(header.returnType, MACRO_RETURN,
207 GET_FIELD_BY_PTR(infoStructName, MACRO_RETURN))));
209 for (int i = 0; i < header.args.size(); i++) {
210 String type = header.args.get(i).type, var = header.args.get(i).name;
211 code.add((DECLARE_DEFINE(type, var,
212 GET_FIELD_BY_PTR(infoStructName, var))));
217 if (!construct.condition.equals("")) {
218 code.add(DECLARE_DEFINE("bool", MACRO_COND, construct.condition));
221 if (!construct.check.equals("")) {
222 code.add(ASSIGN("check_passed", construct.check));
223 code.add("if (!check_passed) return false;");
226 if (construct.action.size() > 0) {
227 code.addAll(construct.action);
230 if (!construct.postCheck.equals("")) {
231 code.add(ASSIGN("check_passed", construct.postCheck));
232 code.add("if (!check_passed) return false;");
235 if (construct.postAction.size() > 0) {
236 code.addAll(construct.postAction);
238 // Return true finally
239 code.add("return true;");
246 private static HashSet<String> getAllHeaders(SemanticsChecker semantics) {
247 HashSet<String> headers = new HashSet<String>();
248 for (String interfaceName : semantics.interfaceName2Construct.keySet()) {
249 File f = semantics.interfaceName2Construct.get(interfaceName).file;
250 headers.addAll(semantics.srcFilesInfo.get(f).headers);
255 private static void makeFunctionStatic(ArrayList<String> funcDefine) {
256 String headLine = funcDefine.get(0);
257 headLine = "inline static " + headLine;
258 funcDefine.set(0, headLine);
261 private static String makeVariablesStatic(VariableDeclaration varDecl) {
262 String res = "static " + varDecl.type + " " + varDecl.name + ";";
266 private static FunctionHeader getFunctionHeader(SemanticsChecker semantics,
267 Construct construct) {
268 ArrayList<String> content = semantics.srcFilesInfo.get(construct.file).content;
269 String headerLine = content.get(construct.beginLineNum), templateLine = null;
270 if (headerLine.startsWith("template")) {
271 templateLine = headerLine;
272 headerLine = content.get(construct.beginLineNum + 1);
274 headerLine = headerLine.substring(0, headerLine.indexOf(')') + 1);
276 FunctionHeader header = SpecParser.parseFuncHeader(headerLine);
277 if (templateLine != null) {
278 ArrayList<VariableDeclaration> templateArgs = SpecParser
279 .getTemplateArg(templateLine);
280 header.setTemplateList(templateArgs);
283 } catch (ParseException e) {
289 public static ArrayList<String> generateGlobalVarDeclaration(
290 SemanticsChecker semantics, GlobalConstruct construct) {
291 ArrayList<String> newCode = new ArrayList<String>();
292 HashSet<String> allHeaders = getAllHeaders(semantics);
294 // All headers needed by the interface decalration
295 newCode.add(COMMENT("Include all the header files that contains the interface declaration"));
296 for (String header : allHeaders) {
297 newCode.add(INCLUDE(header));
300 // Other necessary headers
301 newCode.add(INCLUDE(HEADER_STDLIB));
302 newCode.add(INCLUDE(HEADER_STDINT));
303 newCode.add(INCLUDE(HEADER_CDSANNOTATE));
304 newCode.add(INCLUDE(HEADER_COMMON));
305 newCode.add(INCLUDE(HEADER_SPEC_LIB));
306 newCode.add(INCLUDE(HEADER_SPECANNOTATION));
309 SequentialDefineSubConstruct code = construct.code;
310 // User-defined structs first
311 newCode.add(COMMENT("All other user-defined structs"));
312 ArrayList<ArrayList<String>> declareStructs = code.declareStructs;
313 for (int i = 0; i < declareStructs.size(); i++) {
314 ArrayList<String> declareStruct = declareStructs.get(i);
315 newCode.addAll(declareStruct);
318 // User-defined variables
319 ArrayList<VariableDeclaration> varDecls = code.declareVar;
320 for (int i = 0; i < varDecls.size(); i++) {
321 VariableDeclaration varDecl = varDecls.get(i);
322 // Don't forget to make them static
323 newCode.add(makeVariablesStatic(varDecl));
325 // User-defined functions
326 newCode.add(COMMENT("All other user-defined functions"));
327 ArrayList<ArrayList<String>> defineFuncs = code.defineFuncs;
328 for (int i = 0; i < defineFuncs.size(); i++) {
329 ArrayList<String> defineFunc = defineFuncs.get(i);
330 makeFunctionStatic(defineFunc);
331 newCode.addAll(defineFunc);
335 for (String interfaceName : semantics.interfaceName2Construct.keySet()) {
336 InterfaceConstruct iConstruct = semantics.interfaceName2Construct
338 FunctionHeader funcHeader = getFunctionHeader(semantics, iConstruct);
339 // Define necessary info structure
340 if (!funcHeader.returnType.equals("void")
341 || funcHeader.args.size() > 0) {
342 newCode.add(COMMENT("Definition of interface info struct: "
344 newCode.addAll(DEFINE_INFO_STRUCT(interfaceName, funcHeader));
345 newCode.add(COMMENT("End of info struct definition: "
350 // Define ID function
351 newCode.add(COMMENT("ID function of interface: " + interfaceName));
352 newCode.addAll(DEFINE_ID_FUNC(interfaceName, iConstruct.idCode));
353 newCode.add(COMMENT("End of ID function: " + interfaceName));
356 // Define check_action function
357 newCode.add(COMMENT("Check action function of interface: "
359 newCode.addAll(DEFINE_CHECK_ACTION_FUNC(iConstruct, funcHeader));
360 newCode.add(COMMENT("End of check action function: "
364 // Interface function pointer table
365 String interfaceSize = Integer
366 .toString(semantics.interfaceName2Construct.size());
367 newCode.add(DEFINE("INTERFACE_SIZE", interfaceSize));
368 newCode.add(DECLARE("void**", "func_ptr_table"));
371 newCode.add(COMMENT("Define function for sequential code initialization"));
372 newCode.add("inline static void __sequential_init() {");
373 // Init func_ptr_table
374 newCode.add(COMMENT("Init func_ptr_table"));
375 newCode.add(ASSIGN("func_ptr_table", "(void**) malloc(sizeof(void*) * "
376 + semantics.interface2Num.size() + " * 2)"));
377 for (String interfaceName : semantics.interfaceName2Construct.keySet()) {
378 String interfaceNum = Integer.toString(semantics.interface2Num
379 .get(interfaceName));
380 newCode.add(ASSIGN("func_ptr_table[2 * " + interfaceNum + "]",
381 "(void*) &" + interfaceName + "_id"));
382 newCode.add(ASSIGN("func_ptr_table[2 * " + interfaceNum + " + 1]",
383 "(void*) &" + interfaceName + "_check_action"));
386 // Init user-defined variables
387 newCode.addAll(construct.code.initVar);
388 // Pass function table info
389 newCode.add(COMMENT("Pass function table info"));
390 String structName = "anno_func_table_init", anno = "func_init";
391 newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_FUNC_TABLE_INIT, structName));
392 newCode.add(ASSIGN_TO_PTR(structName, "size", "INTERFACE_SIZE"));
393 newCode.add(ASSIGN_TO_PTR(structName, "table", "func_ptr_table"));
394 newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
395 newCode.add(ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_FUNC_TABLE_INIT));
396 newCode.add(ASSIGN_TO_PTR(anno, "annotation", structName));
397 newCode.add(ANNOTATE(anno));
399 // Pass Happens-before relationship
400 newCode.addAll(generateHBInitAnnotation(semantics));
402 newCode.add(COMMENT("End of Global construct generation in class"));
408 public static ArrayList<String> generateStaticVarDefine(
409 SemanticsChecker semantics, GlobalConstruct construct) {
410 ArrayList<String> newCode = new ArrayList<String>();
411 String className = semantics.getClassName();
412 if (className == null)
413 return newCode; // No need to define any static variables
414 String templateList = semantics.getTemplateStr();
416 if (templateList == null) {
417 varPrefix = className + "::";
419 varPrefix = className + templateList + "::";
421 String templateDecl = semantics.getTemplateFullStr();
422 if (templateList == null) {
423 newCode.add(DECLARE("void**", varPrefix + "func_ptr_table"));
424 for (int i = 0; i < construct.code.declareVar.size(); i++) {
425 VariableDeclaration varDecl = construct.code.declareVar.get(i);
426 newCode.add(DECLARE(varDecl.type, varPrefix + varDecl.name));
429 newCode.add(templateDecl);
430 newCode.add(DECLARE("void**", varPrefix + "func_ptr_table"));
431 for (int i = 0; i < construct.code.declareVar.size(); i++) {
432 VariableDeclaration varDecl = construct.code.declareVar.get(i);
433 newCode.add(templateDecl);
434 newCode.add(DECLARE(varDecl.type, varPrefix + varDecl.name));
440 private static ArrayList<String> generateHBInitAnnotation(
441 SemanticsChecker semantics) {
442 ArrayList<String> newCode = new ArrayList<String>();
443 int hbConditionInitIdx = 0;
444 for (ConditionalInterface left : semantics.getHBConditions().keySet()) {
445 for (ConditionalInterface right : semantics.getHBConditions().get(
447 String structVarName = "hbConditionInit" + hbConditionInitIdx;
448 String annotationVarName = "hb_init" + hbConditionInitIdx;
449 hbConditionInitIdx++;
450 String interfaceNumBefore = Integer
451 .toString(semantics.interface2Num
452 .get(left.interfaceName)), hbLabelNumBefore = Integer
453 .toString(semantics.hbLabel2Num
454 .get(left.hbConditionLabel)), interfaceNumAfter = Integer
455 .toString(semantics.interface2Num
456 .get(right.interfaceName)), hbLabelNumAfter = Integer
457 .toString(semantics.hbLabel2Num
458 .get(right.hbConditionLabel));
459 newCode.add(COMMENT(left + " -> " + right));
461 newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_HB_INIT,
463 newCode.add(ASSIGN_TO_PTR(structVarName,
464 "interface_num_before", interfaceNumBefore));
465 newCode.add(ASSIGN_TO_PTR(structVarName,
466 "hb_condition_num_before", hbLabelNumBefore));
467 newCode.add(ASSIGN_TO_PTR(structVarName, "interface_num_after",
469 newCode.add(ASSIGN_TO_PTR(structVarName,
470 "hb_condition_num_after", hbLabelNumAfter));
472 newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION,
474 newCode.add(ASSIGN_TO_PTR(annotationVarName,
475 SPEC_ANNOTATION_FIELD_TYPE, SPEC_ANNO_TYPE_HB_INIT));
476 newCode.add(ASSIGN_TO_PTR(annotationVarName,
477 SPEC_ANNOTATION_FIELD_ANNO, structVarName));
478 newCode.add(ANNOTATE(annotationVarName));
484 public static ArrayList<String> generateEntryPointInitCall() {
485 ArrayList<String> newCode = new ArrayList<String>(1);
486 newCode.add("__sequential_init();");
490 // Only generate the declaration of the wrapper, don't do any renaming
491 public static ArrayList<String> generateInterfaceWrapperDeclaration(
492 SemanticsChecker semantics, InterfaceConstruct construct) {
493 ArrayList<String> newCode = new ArrayList<String>();
494 FunctionHeader header = getFunctionHeader(semantics, construct);
495 newCode.add(COMMENT("Declaration of the wrapper"));
496 String templateStr = header.getTemplateFullStr();
497 newCode.add(templateStr);
498 newCode.add(header.getFuncStr() + ";");
504 // Only generate the definition of the wrapper, don't do any renaming
505 public static ArrayList<String> generateInterfaceWrapperDefinition(
506 SemanticsChecker semantics, InterfaceConstruct construct) {
507 ArrayList<String> newCode = new ArrayList<String>();
508 String interfaceName = construct.name;
509 // Generate necessary header file (might be redundant but never mind)
510 newCode.add(INCLUDE(HEADER_STDLIB));
511 newCode.add(INCLUDE(HEADER_CDSANNOTATE));
512 newCode.add(INCLUDE(HEADER_SPECANNOTATION));
513 newCode.add(INCLUDE(HEADER_SPEC_LIB));
515 FunctionHeader header = getFunctionHeader(semantics, construct);
516 String interfaceNum = Integer.toString(semantics.interface2Num
517 .get(construct.name));
519 newCode.add(header.getTemplateFullStr());
520 newCode.add(header.getFuncStr() + " {");
521 // Wrapper function body
522 newCode.add(COMMENT("Interface begins"));
524 String structName = "interface_begin";
525 newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_INTERFACE_BEGIN,
527 newCode.add(ASSIGN_TO_PTR(structName, "interface_num", interfaceNum));
528 String anno = "annotation_interface_begin";
529 newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
530 newCode.add(ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_INTERFACE_BEGIN));
531 newCode.add(ASSIGN_TO_PTR(anno, "annotation", structName));
532 newCode.add(ANNOTATE(anno));
533 // Call original renamed function
534 if (header.returnType.equals("void")) {
535 newCode.add(header.getRenamedCall(SPEC_INTERFACE_WRAPPER) + ";");
537 newCode.add(DECLARE_DEFINE(header.returnType, MACRO_RETURN,
538 header.getRenamedCall(SPEC_INTERFACE_WRAPPER)));
541 for (String label : construct.hbConditions.keySet()) {
542 String condition = construct.hbConditions.get(label);
543 String hbCondNum = Integer.toString(semantics.hbLabel2Num
545 newCode.add("if " + BRACE(condition) + " {");
546 structName = "hb_condition";
547 newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_HB_CONDITION, structName));
548 newCode.add(ASSIGN_TO_PTR(structName, "interface_num", interfaceNum));
550 newCode.add(ASSIGN_TO_PTR(structName, "hb_condition_num", hbCondNum));
551 anno = "annotation_hb_condition";
552 newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
553 newCode.add(ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_HB_CONDITION));
554 newCode.add(ASSIGN_TO_PTR(anno, "annotation", structName));
555 newCode.add(ANNOTATE(anno));
559 // Also add the true condition if any
560 if (semantics.containsConditionalInterface(new ConditionalInterface(
561 interfaceName, ""))) {
562 structName = "hb_condition";
563 newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_HB_CONDITION, structName));
564 newCode.add(ASSIGN_TO_PTR(structName, "interface_num", interfaceNum));
565 newCode.add(ASSIGN_TO_PTR(structName, "hb_condition_num", "0"));
566 anno = "annotation_hb_condition";
567 newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
568 newCode.add(ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_HB_CONDITION));
569 newCode.add(ASSIGN_TO_PTR(anno, "annotation", structName));
570 newCode.add(ANNOTATE(anno));
574 String infoStructType = null, infoName = null;
575 if (!header.returnType.equals("void") || header.args.size() > 0) {
576 infoStructType = interfaceName + "_info";
578 newCode.add(DECLARE_DEFINE(infoStructType + "*", infoName,
579 BRACE(infoStructType + "*") + " malloc(sizeof("
580 + infoStructType + "))"));
581 if (!header.returnType.equals("void")) {
582 newCode.add(ASSIGN_TO_PTR(infoName, MACRO_RETURN, MACRO_RETURN));
584 for (int i = 0; i < header.args.size(); i++) {
585 String argName = header.args.get(i).name;
586 newCode.add(ASSIGN_TO_PTR(infoName, argName, argName));
591 structName = "interface_end";
592 anno = "annoation_interface_end";
593 newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_INTERFACE_END, structName));
594 newCode.add(ASSIGN_TO_PTR(structName, "interface_num", interfaceNum));
595 newCode.add(ASSIGN_TO_PTR(structName, "info", infoName));
596 newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
597 newCode.add(ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_INTERFACE_END));
598 newCode.add(ASSIGN_TO_PTR(anno, "annotation", structName));
599 newCode.add(ANNOTATE(anno));
600 // Return __RET__ if it's not void
601 if (!header.returnType.equals("void")) {
602 newCode.add("return " + MACRO_RETURN + ";");
604 // End of the wrapper function
607 // printCode(newCode);
611 // Rename the interface name for declaration or definition
612 public static void renameInterface(SemanticsChecker semantics,
613 Construct construct) {
614 FunctionHeader header = getFunctionHeader(semantics, construct);
615 ArrayList<String> content = semantics.srcFilesInfo.get(construct.file).content;
616 int lineNum = construct.beginLineNum;
617 String headerLine = content.get(construct.beginLineNum);
618 if (headerLine.startsWith("template")) {
619 headerLine = content.get(construct.beginLineNum + 1);
622 String newLine = header.getRenamedHeader(SPEC_INTERFACE_WRAPPER)
625 if (construct instanceof InterfaceConstruct) {
626 InterfaceConstruct iConstruct = (InterfaceConstruct) construct;
627 InterfaceDefineConstruct defineConstruct = semantics.interfaceName2DefineConstruct
628 .get(iConstruct.name);
629 if (defineConstruct != null) { // There is a defineConstruct
630 newLine = newLine + " ;";
631 renameInterface(semantics, defineConstruct);
632 } else { // This is a declare & define construct
633 newLine = newLine + " {";
636 newLine = newLine + " {";
638 content.set(lineNum, newLine);
641 public static void addAtomicReturn(SemanticsChecker semantics,
642 Construct construct) {
643 int lineNum = construct.beginLineNum - 1;
644 ArrayList<String> content = semantics.srcFilesInfo.get(construct.file).content;
645 String oldLine = content.get(lineNum);
646 String newLine = "uint64_t " + MACRO_ATOMIC_RETURN + " = " + oldLine;
647 content.set(lineNum, newLine);
650 public static ArrayList<String> generatePotentialCPDefine(
651 SemanticsChecker semantics, PotentialCPDefineConstruct construct) {
652 ArrayList<String> newCode = new ArrayList<String>();
653 // Add atomic return variable if the predicate accesses to it
654 if (construct.condition.indexOf(MACRO_ATOMIC_RETURN) != -1) {
655 addAtomicReturn(semantics, construct);
657 // Generate redundant header files
658 newCode.add(COMMENT("Automatically generated code for potential commit point: "
660 newCode.add(COMMENT("Include redundant headers"));
661 newCode.add(INCLUDE(HEADER_STDINT));
662 newCode.add(INCLUDE(HEADER_CDSANNOTATE));
663 newCode.add(INCLUDE(HEADER_SPECANNOTATION));
666 newCode.add("if (" + construct.condition + ") {");
667 String structName = "potential_cp_define", anno = "annotation_potential_cp_define";
668 newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_POTENTIAL_CP_DEFINE,
670 String labelNum = Integer.toString(semantics.commitPointLabel2Num
671 .get(construct.label));
672 newCode.add(ASSIGN_TO_PTR(structName, "label_num", labelNum));
673 newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
674 newCode.add(ASSIGN_TO_PTR(anno, "type",
675 SPEC_ANNO_TYPE_POTENTIAL_CP_DEFINE));
676 newCode.add(ASSIGN_TO_PTR(anno, "annotation", structName));
677 newCode.add(ANNOTATE(anno));
682 public static ArrayList<String> generateCPDefineCheck(
683 SemanticsChecker semantics, CPDefineCheckConstruct construct) {
684 ArrayList<String> newCode = new ArrayList<String>();
685 // Add atomic return variable if the predicate accesses to it
686 if (construct.condition.indexOf(MACRO_ATOMIC_RETURN) != -1) {
687 addAtomicReturn(semantics, construct);
689 // Generate redundant header files
690 newCode.add(COMMENT("Automatically generated code for commit point define check: "
692 newCode.add(COMMENT("Include redundant headers"));
693 newCode.add(INCLUDE(HEADER_STDINT));
694 newCode.add(INCLUDE(HEADER_CDSANNOTATE));
697 newCode.add("if (" + construct.condition + ") {");
698 String structName = "cp_define_check", anno = "annotation_cp_define_check";
699 newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_CP_DEFINE_CHECK, structName));
700 String labelNum = Integer.toString(semantics.commitPointLabel2Num
701 .get(construct.label));
702 newCode.add(ASSIGN_TO_PTR(structName, "label_num", labelNum));
703 newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
704 newCode.add(ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_CP_DEFINE_CHECK));
705 newCode.add(ASSIGN_TO_PTR(anno, "annotation", structName));
706 newCode.add(ANNOTATE(anno));
711 public static ArrayList<String> generateCPDefine(
712 SemanticsChecker semantics, CPDefineConstruct construct) {
713 ArrayList<String> newCode = new ArrayList<String>();
714 // Generate redundant header files
715 newCode.add(COMMENT("Automatically generated code for commit point define check: "
719 newCode.add("if (" + construct.condition + ") {");
720 String structName = "cp_define", anno = "annotation_cp_define";
721 newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_CP_DEFINE, structName));
722 String labelNum = Integer.toString(semantics.commitPointLabel2Num
723 .get(construct.label));
724 newCode.add(ASSIGN_TO_PTR(structName, "label_num", labelNum));
725 newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
726 newCode.add(ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_CP_DEFINE));
727 newCode.add(ASSIGN_TO_PTR(anno, "annotation", structName));
728 newCode.add(ANNOTATE(anno));