1 package edu.uci.eecs.codeGenerator;
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.HashSet;
6 import java.util.regex.Matcher;
7 import java.util.regex.Pattern;
8 import java.io.BufferedWriter;
10 import java.io.FileWriter;
11 import java.io.IOException;
13 import edu.uci.eecs.specExtraction.Code;
14 import edu.uci.eecs.specExtraction.CommutativityRule;
15 import edu.uci.eecs.specExtraction.DefineConstruct;
16 import edu.uci.eecs.specExtraction.EntryConstruct;
17 import edu.uci.eecs.specExtraction.FunctionHeader;
18 import edu.uci.eecs.specExtraction.GlobalConstruct;
19 import edu.uci.eecs.specExtraction.InterfaceConstruct;
20 import edu.uci.eecs.specExtraction.OPConstruct;
21 import edu.uci.eecs.specExtraction.SpecExtractor;
22 import edu.uci.eecs.specExtraction.SpecNaming;
23 import edu.uci.eecs.specExtraction.VariableDeclaration;
27 * Some utility functions for generating specification checking code.
33 public class CodeGeneratorUtils {
35 public static void PrintCode(ArrayList<String> code) {
36 for (int i = 0; i < code.size(); i++) {
37 System.out.println(code.get(i));
41 public static String Comment(String comment) {
42 return "/** " + comment + " */";
45 public static String ShortComment(String comment) {
46 return "// " + comment;
49 public static String IncludeHeader(String header) {
50 return "#include " + header;
53 public static String Brace(String val) {
54 return "(" + val + ")";
57 public static String Quote(String val) {
58 return "\"" + val + "\"";
61 public static String Assign(String varName, String val) {
62 return varName + " = " + val + ";";
65 public static String AssignToPtr(String structName, String field, String val) {
66 return structName + "->" + field + " = " + val + ";";
69 public static String Declare(String type, String name) {
70 return type + " " + name + ";";
73 public static String Declare(VariableDeclaration varDecl) {
74 return Declare(varDecl.type, varDecl.name);
77 public static String DeclareDefine(String type, String var, String val) {
78 return type + " " + var + " = " + val + ";";
83 * Insert a number of tabs at the beginning of the line.
89 * The number of tabs to be inserted
90 * @return A line that starts with the specific inserted tabs
92 public static String TabbedLine(String line, int tabCnt) {
94 for (int i = 0; i < tabCnt; i++)
102 * Insert a tab at the beginning of the line.
107 * @return A line that starts with one inserted tab
109 public static String TabbedLine(String line) {
115 * This function generates the code for the header file that our
116 * specification generates automatically --- cdsspec-generated.h.
120 * The SpecExtractor that contains the extracted information
121 * @return The generated code
123 public static Code GenerateCDSSpecHeaderFile(SpecExtractor extractor) {
124 HashSet<String> headerFiles = extractor.headerFiles;
125 GlobalConstruct globalConstruct = extractor.getGlobalConstruct();
126 HashMap<File, ArrayList<InterfaceConstruct>> interfaceListMap = extractor.interfaceListMap;
127 HashSet<String> OPLabelSet = extractor.OPLabelSet;
129 Code code = new Code();
131 // Add auto-generated comments
133 code.addLine(TabbedLine("This is a header file auto-generated by CDSSpec compiler; together, CDSSpec"));
134 code.addLine(TabbedLine("compiler should have generated the accompanying implementation file that"));
135 code.addLine(TabbedLine("implements the some functions declared in this file. In order to instrument"));
136 code.addLine(TabbedLine("your benchmark for CDSSpec checker to check, you should include this header"));
137 code.addLine(TabbedLine("file in every file you use an CDSSpec annotation. Note that it should be"));
138 code.addLine(TabbedLine("placed in the end of all other header files. Currently we require a C++"));
139 code.addLine(TabbedLine("compiler that supports C++11."));
143 code.addLine("#ifndef _"
144 + SpecNaming.CDSSpecGeneratedName.toUpperCase().replace('-',
146 code.addLine("#define _"
147 + SpecNaming.CDSSpecGeneratedName.toUpperCase().replace('-',
151 // FIXME: We have included ad-hoc header files here
152 // System included headers
153 code.addLine(ShortComment("System included headers go here"));
154 code.addLine(IncludeHeader(SpecNaming.SPECANNOTATION_API));
155 code.addLine(IncludeHeader(SpecNaming.STDLIB));
159 // Users included headers
160 code.addLine(ShortComment("User included headers go here"));
161 for (String header : headerFiles) {
162 code.addLine(IncludeHeader(header));
166 // Decalre extern "C" --- begin
167 code.addLine("#ifdef __cplusplus");
168 code.addLine("extern \"C\" {");
169 code.addLine("#endif");
172 code.addLine(ShortComment("Declaration of some c-strings (CSTR)"));
174 // Interface name strings
175 code.addLine(ShortComment("Interface name strings"));
176 for (File file : interfaceListMap.keySet()) {
177 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
178 for (InterfaceConstruct construct : list) {
179 String name = construct.getName();
180 code.addLine(Declare("extern " + SpecNaming.CString,
181 SpecNaming.AppendStr(name)));
186 // Ordering points label strings
187 code.addLine(ShortComment("Ordering points label strings"));
188 for (String label : OPLabelSet) {
189 code.addLine(Declare("extern " + SpecNaming.CString,
190 SpecNaming.AppendStr(label)));
194 // Declare customized value struct
195 for (File file : interfaceListMap.keySet()) {
196 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
197 for (InterfaceConstruct construct : list) {
198 // Declare custom value struct for the interface
199 String name = construct.getName();
200 code.addLine(ShortComment("Declare custom value struct for "
202 code.addLine("typedef struct " + name + " {");
203 FunctionHeader funcHeader = construct.getFunctionHeader();
205 if (!funcHeader.returnType.equals("void"))
206 code.addLine(TabbedLine(Declare(funcHeader.returnType,
209 for (VariableDeclaration decl : funcHeader.args) {
210 code.addLine(TabbedLine(Declare(decl)));
212 code.addLine("} " + name + ";");
217 // Declare INIT annotation instrumentation function
218 code.addLine(ShortComment("Declare INIT annotation instrumentation function"));
219 code.addLine("void _createInitAnnotation();");
222 // Decalre extern "C" --- begin
223 code.addLine("#ifdef __cplusplus");
225 code.addLine("#endif");
229 code.addLine("#endif");
236 * This function generates the code for the CPP file that our specification
237 * generates automatically --- cdsspec-generated.cc.
241 * The SpecExtractor that contains the extracted information
242 * @return The generated code
244 public static Code GenerateCDSSpecCPPFile(SpecExtractor extractor) {
245 GlobalConstruct globalConstruct = extractor.getGlobalConstruct();
246 HashMap<File, ArrayList<InterfaceConstruct>> interfaceListMap = extractor.interfaceListMap;
247 HashSet<String> OPLabelSet = extractor.OPLabelSet;
249 Code code = new Code();
252 // Add auto-generated comments
254 code.addLine(TabbedLine("This is an implementation file auto-generated by CDSSpec compiler to"));
255 code.addLine(TabbedLine("instrument your benchmark for CDSSpec checker to check. Currently we require"));
256 code.addLine(TabbedLine("a C++ compiler that supports C++11."));
260 code.addLine("#include " + SpecNaming.CDSSpecGeneratedHeader);
261 code.addLine("#include " + SpecNaming.CDSANNOTATE);
262 code.addLine("#include " + SpecNaming.SPEC_COMMON);
263 code.addLine("#include " + SpecNaming.METHODCALL);
264 code.addLine("#include " + SpecNaming.CDSSPEC);
265 code.addLine("#include " + SpecNaming.SPECANNOTATION);
269 // Declare customized StateStruct
270 code.addLine(ShortComment("Declare customized StateStruct"));
271 code.addLine("typedef struct " + SpecNaming.StateStruct + " {");
272 for (VariableDeclaration decl : globalConstruct.declState) {
273 code.addLine(TabbedLine(Declare(decl)));
276 // Define state destructor
277 code.addLine(TabbedLine(ShortComment("Define state destructor")));
278 code.addLine(TabbedLine("~" + SpecNaming.StateStruct + "() {"));
279 if (!globalConstruct.autoGenClear) {
280 code.addLine(TabbedLine(
281 ShortComment("Execute user-defined state clear code"), 2));
283 code.addLine(TabbedLine(
284 ShortComment("Execute auto-generated state clear code"), 2));
286 globalConstruct.clearState.align(2);
287 code.addLines(globalConstruct.clearState);
288 code.addLine(TabbedLine("}"));
291 code.addLine(TabbedLine("SNAPSHOTALLOC"));
293 code.addLine("} " + SpecNaming.StateStruct + ";");
297 code.addLine(ShortComment("Definition of some c-strings (CSTR)"));
298 code.addLine(ShortComment("A special empty string"));
299 code.addLine(DeclareDefine(SpecNaming.CString, SpecNaming.EmptyCString,
303 // Interface name strings
304 code.addLine(ShortComment("Interface name strings"));
305 for (File file : interfaceListMap.keySet()) {
306 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
307 for (InterfaceConstruct construct : list) {
308 String name = construct.getName();
309 code.addLine(DeclareDefine(SpecNaming.CString,
310 SpecNaming.AppendStr(name), Quote(name)));
315 // Commutativity rule strings
316 code.addLine(ShortComment("Commutativity rule strings"));
317 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
318 CommutativityRule rule = globalConstruct.commutativityRules
320 code.addLine(DeclareDefine(SpecNaming.CString,
321 SpecNaming.AppendStr(SpecNaming.Commutativity + i),
322 Quote(rule.toString())));
326 // Ordering points label strings
327 code.addLine(ShortComment("Ordering points label strings"));
328 for (String label : OPLabelSet) {
329 code.addLine(DeclareDefine(SpecNaming.CString,
330 SpecNaming.AppendStr(label), Quote(label)));
334 // Special function name strings
335 code.addLine(ShortComment("Special function name strings"));
336 code.addLine(DeclareDefine(SpecNaming.CString,
337 SpecNaming.AppendStr(SpecNaming.InitalState), Quote("_"
338 + SpecNaming.InitalState.toLowerCase())));
339 code.addLine(DeclareDefine(SpecNaming.CString,
340 SpecNaming.AppendStr(SpecNaming.CopyState), Quote("_"
341 + SpecNaming.CopyState.toLowerCase())));
342 code.addLine(DeclareDefine(SpecNaming.CString,
343 SpecNaming.AppendStr(SpecNaming.ClearState), Quote("_"
344 + SpecNaming.ClearState.toLowerCase())));
345 code.addLine(DeclareDefine(SpecNaming.CString,
346 SpecNaming.AppendStr(SpecNaming.FinalState), Quote("_"
347 + SpecNaming.FinalState.toLowerCase())));
348 code.addLine(DeclareDefine(SpecNaming.CString,
349 SpecNaming.AppendStr(SpecNaming.PrintState), Quote("_"
350 + SpecNaming.PrintState.toLowerCase())));
353 // Interface name strings
354 for (File file : interfaceListMap.keySet()) {
355 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
356 for (InterfaceConstruct construct : list) {
357 String name = construct.getName();
358 code.addLine(ShortComment(name + " function strings"));
360 String tmpFunc = name + "_" + SpecNaming.Transition;
361 code.addLine(DeclareDefine(SpecNaming.CString,
362 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
364 tmpFunc = name + "_" + SpecNaming.PreCondition;
365 if (!construct.preCondition.isEmpty())
366 code.addLine(DeclareDefine(SpecNaming.CString,
367 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
369 code.addLine(DeclareDefine(SpecNaming.CString,
370 SpecNaming.AppendStr(tmpFunc),
371 SpecNaming.EmptyCString));
373 tmpFunc = name + "_" + SpecNaming.PostCondition;
374 if (!construct.postCondition.isEmpty())
375 code.addLine(DeclareDefine(SpecNaming.CString,
376 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
378 code.addLine(DeclareDefine(SpecNaming.CString,
379 SpecNaming.AppendStr(tmpFunc),
380 SpecNaming.EmptyCString));
382 tmpFunc = name + "_" + SpecNaming.PrintValue;
383 if (!construct.print.isEmpty())
384 code.addLine(DeclareDefine(SpecNaming.CString,
385 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
387 code.addLine(DeclareDefine(SpecNaming.CString,
388 SpecNaming.AppendStr(tmpFunc),
389 SpecNaming.EmptyCString));
395 code.addLine(ShortComment("Define @" + SpecNaming.InitalState));
396 code.addLine("void _" + SpecNaming.InitalState.toLowerCase() + "("
397 + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
398 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
399 + SpecNaming.StateInst, "new " + SpecNaming.StateStruct)));
401 for (VariableDeclaration decl : globalConstruct.declState) {
402 code.addLine(TabbedLine("#define " + decl.name + " "
403 + SpecNaming.StateInst + "->" + decl.name));
405 if (!globalConstruct.autoGenInitial)
406 code.addLine(TabbedLine(ShortComment("User-defined state intialization code")));
408 // Auto-generated the initialization function
409 code.addLine(TabbedLine(ShortComment("Auto-generated state intialization code")));
410 // Align the code with one tab
411 globalConstruct.initState.align(1);
412 code.addLines(globalConstruct.initState);
414 for (VariableDeclaration decl : globalConstruct.declState) {
415 code.addLine(TabbedLine("#undef " + decl.name));
418 code.addLine(TabbedLine(AssignToPtr(SpecNaming.Method1,
419 SpecNaming.StateInst, SpecNaming.StateInst)));
424 code.addLine(ShortComment("Define @" + SpecNaming.CopyState));
425 code.addLine("void _" + SpecNaming.CopyState.toLowerCase() + "("
426 + SpecNaming.Method + " " + "dest, " + SpecNaming.Method
428 // StateStruct *OLD = (StateStruct*) src->state;
429 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
430 + SpecNaming.OldStateInst, Brace(SpecNaming.StateStruct + "*")
431 + " src->" + SpecNaming.StateInst)));
432 // StateStruct *NEW = new StateStruct;
433 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
434 + SpecNaming.NewStateInst, "new " + SpecNaming.StateStruct)));
435 if (!globalConstruct.autoGenCopy)
436 code.addLine(TabbedLine(ShortComment("User-defined state copy statements")));
438 // Auto-generated the copy function
439 code.addLine(TabbedLine(ShortComment("Auto-generated state copy statements")));
440 globalConstruct.copyState.align(1);
441 code.addLines(globalConstruct.copyState);
443 code.addLine(TabbedLine(AssignToPtr("dest", SpecNaming.StateInst,
444 SpecNaming.NewStateInst)));
449 code.addLine(ShortComment("Define @" + SpecNaming.ClearState));
450 code.addLine("void _" + SpecNaming.ClearState.toLowerCase() + "("
451 + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
452 // Retrieve the state
453 code.addLine(TabbedLine(ShortComment("Retrieve the state")));
454 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
455 + SpecNaming.StateInst, "(" + SpecNaming.StateStruct + "*) "
456 + SpecNaming.Method1 + "->state")));
457 // Explicitly call the state destructor
458 code.addLine(TabbedLine(ShortComment("Explicitly call the state destructor")));
459 code.addLine(TabbedLine("delete " + SpecNaming.StateInst + ";"));
464 if (!globalConstruct.printState.isEmpty()) {
465 code.addLine(ShortComment("Define @" + SpecNaming.PrintState));
466 code.addLine("void _" + SpecNaming.PrintState.toLowerCase() + "("
467 + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
469 // Initialize state struct fields
470 Code fieldsInit = GenerateStateFieldsInitialization(
471 SpecNaming.Method1, SpecNaming.StateInst, globalConstruct);
473 code.addLines(fieldsInit);
475 if (!globalConstruct.autoGenPrint)
476 code.addLine(TabbedLine(ShortComment("Execute user-defined state printing code")));
478 // Auto-generated the copy function
479 code.addLine(TabbedLine(ShortComment("Execute auto-generated state printing code")));
481 // Align the code with one tab
482 globalConstruct.printState.align(1);
483 code.addLines(globalConstruct.printState);
488 // Define @Commutativity
489 code.addLine(ShortComment("Define commutativity checking functions"));
490 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
491 CommutativityRule rule = globalConstruct.commutativityRules
493 code.addLine("bool _check" + SpecNaming.Commutativity + i + "("
494 + SpecNaming.Method + " m1, " + SpecNaming.Method
496 // if (m1->name == _ENQ_str && m2->name == _DEQ_str) {
497 code.addLine(TabbedLine("if (m1->name == "
498 + SpecNaming.AppendStr(rule.method1) + " && m2->name == "
499 + SpecNaming.AppendStr(rule.method2) + ") {"));
500 // Initialize M1 & M2 in commutativity rule
501 // e.g. ENQ *M1 = (ENQ*) m1->value;
502 code.addLine(TabbedLine(
503 DeclareDefine(rule.method1, "*M1", "(" + rule.method1
504 + "*) m1->value"), 2));
505 code.addLine(TabbedLine(
506 DeclareDefine(rule.method2, "*M2", "(" + rule.method2
507 + "*) m2->value"), 2));
508 code.addLine(TabbedLine("return " + rule.condition + ";", 2));
509 code.addLine(TabbedLine("}"));
510 code.addLine(TabbedLine("return false;"));
516 // Define customized interface functions
517 for (File file : interfaceListMap.keySet()) {
518 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
519 for (InterfaceConstruct construct : list) {
520 Code fieldsInit = null;
522 // Define interface functions
523 String name = construct.getName();
524 code.addLine("/********** " + name
525 + " functions **********/");
526 // Define @Transition for INTERFACE
527 code.addLine(ShortComment("Define @" + SpecNaming.Transition
529 code.addLine("void _" + name + "_" + SpecNaming.Transition
530 + "(" + SpecNaming.Method + " " + SpecNaming.Method1
531 + ", " + SpecNaming.Method + " " + SpecNaming.Method2
534 // Initialize value struct fields
535 fieldsInit = GenerateInterfaceFieldsInitialization(
536 SpecNaming.Method2, SpecNaming.InterfaceValueInst,
539 code.addLines(fieldsInit);
541 construct.transition.align(1);
542 code.addLine(TabbedLine(ShortComment("Execute Transition")));
543 code.addLines(construct.transition);
548 // Define @PreCondition
549 if (!construct.preCondition.isEmpty()) {
550 code.addLine(ShortComment("Define @"
551 + SpecNaming.PreCondition + " for " + name));
552 code.addLine("bool _" + name + "_"
553 + SpecNaming.PreCondition + "(" + SpecNaming.Method
554 + " " + SpecNaming.Method1 + ") {");
556 // Initialize value struct fields
557 fieldsInit = GenerateInterfaceFieldsInitialization(
558 SpecNaming.Method1, SpecNaming.InterfaceValueInst,
561 code.addLines(fieldsInit);
563 construct.preCondition.align(1);
564 code.addLine(TabbedLine(ShortComment("Execute PreCondition")));
565 code.addLines(construct.preCondition);
571 // Define @PostCondition
572 if (!construct.postCondition.isEmpty()) {
573 code.addLine(ShortComment("Define @"
574 + SpecNaming.PostCondition + " for " + name));
575 code.addLine("bool _" + name + "_"
576 + SpecNaming.PostCondition + "("
577 + SpecNaming.Method + " " + SpecNaming.Method1
580 // Initialize value struct fields
581 fieldsInit = GenerateInterfaceFieldsInitialization(
582 SpecNaming.Method1, SpecNaming.InterfaceValueInst,
585 code.addLines(fieldsInit);
587 construct.postCondition.align(1);
588 code.addLine(TabbedLine(ShortComment("Execute PostCondition")));
589 code.addLines(construct.postCondition);
595 if (!construct.print.isEmpty()) {
596 code.addLine(ShortComment("Define @"
597 + SpecNaming.PrintValue + " for " + name));
598 code.addLine("void _" + name + "_" + SpecNaming.PrintValue
599 + "(" + SpecNaming.Method + " "
600 + SpecNaming.Method1 + ") {");
601 // Initialize value struct fields
602 fieldsInit = GenerateInterfaceFieldsInitialization(
603 SpecNaming.Method1, SpecNaming.InterfaceValueInst,
606 code.addLines(fieldsInit);
608 construct.print.align(1);
609 if (!construct.autoGenPrint)
610 code.addLine(TabbedLine(ShortComment("Execute user-defined value printing code")));
612 // Auto-generated the value printing function
613 code.addLine(TabbedLine(ShortComment("Execute auto-generated value printing code")));
614 code.addLines(construct.print);
622 // Define INIT annotation instrumentation function
623 code.addLine(ShortComment("Define INIT annotation instrumentation function"));
624 code.addLine("void _createInitAnnotation() {");
626 // Init commutativity rules
627 code.addLine(TabbedLine(ShortComment("Init commutativity rules")));
628 code.addLine(TabbedLine(DeclareDefine("int",
629 SpecNaming.CommutativityRuleSizeInst,
630 Integer.toString(globalConstruct.commutativityRules.size()))));
631 String tmp = SpecNaming.NewSize
632 + Brace(SpecNaming.CommutativityRule + ", sizeof"
633 + Brace(SpecNaming.CommutativityRule) + " * "
634 + SpecNaming.CommutativityRuleSizeInst);
635 code.addLine(TabbedLine(DeclareDefine(SpecNaming.CommutativityRule, "*"
636 + SpecNaming.CommutativityRuleInst, tmp)));
637 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
638 CommutativityRule rule = globalConstruct.commutativityRules
640 code.addLine(TabbedLine(ShortComment("Initialize commutativity rule ")
642 // new( &commuteRules[0] )CommutativityRule(_ENQ_str, _DEQ_str,
643 // _Commutativity1_str, _checkCommutativity1)
645 + Brace(" &" + SpecNaming.CommutativityRuleInst + "["
646 + (i - 1) + "] ") + SpecNaming.CommutativityRule
647 + "(" + SpecNaming.AppendStr(rule.method1) + ", "
648 + SpecNaming.AppendStr(rule.method2) + ", "
649 + SpecNaming.AppendStr(SpecNaming.Commutativity + i) + ", "
650 + "_check" + SpecNaming.Commutativity + i + ");";
651 code.addLine(TabbedLine(line));
654 // Initialize AnnoInit
655 code.addLine(TabbedLine(ShortComment("Initialize AnnoInit")));
656 // AnnoInit *init = new AnnoInit(
657 code.addLine(TabbedLine(SpecNaming.AnnoInit + " *"
658 + SpecNaming.AnnoInitInst + " = new " + SpecNaming.AnnoInit
660 // new NamedFunction(_Initial_str, INITIAL, (void*) _initial),
661 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
662 + SpecNaming.AppendStr(SpecNaming.InitalState) + ", "
663 + SpecNaming.InitalState.toUpperCase() + ", " + "(void*) _"
664 + SpecNaming.InitalState.toLowerCase() + "),", 2));
665 // new NamedFunction(_Final_str, FINAL, (void*) NULL_FUNC),
666 line = "new " + SpecNaming.NamedFunction + "("
667 + SpecNaming.AppendStr(SpecNaming.FinalState) + ", "
668 + SpecNaming.FinalState.toUpperCase() + ", " + "(void*) ";
669 if (globalConstruct.finalState.isEmpty()) {
670 line = line + SpecNaming.NullFunc + "),";
672 line = line + "_" + SpecNaming.FinalState.toUpperCase();
674 code.addLine(TabbedLine(line, 2));
675 // new NamedFunction(_Copy_str, COPY, (void*) _copy),
676 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
677 + SpecNaming.AppendStr(SpecNaming.CopyState) + ", "
678 + SpecNaming.CopyState.toUpperCase() + ", " + "(void*) _"
679 + SpecNaming.CopyState.toLowerCase() + "),", 2));
680 // new NamedFunction(_Clear_str, CLEAR, (void*) _clear),
681 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
682 + SpecNaming.AppendStr(SpecNaming.ClearState) + ", "
683 + SpecNaming.ClearState.toUpperCase() + ", " + "(void*) _"
684 + SpecNaming.ClearState.toLowerCase() + "),", 2));
685 // new NamedFunction(_Print_str, PRINT_STATE, (void*) _print),
686 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
687 + SpecNaming.AppendStr(SpecNaming.PrintState) + ", "
688 + SpecNaming.PrintStateType + ", " + "(void*) _"
689 + SpecNaming.PrintState.toLowerCase() + "),", 2));
690 // commuteRules, CommuteRuleSize);
691 code.addLine(TabbedLine(SpecNaming.CommutativityRuleInst + ", "
692 + SpecNaming.CommutativityRuleSizeInst + ");", 2));
695 // Declare StateFunctions map
696 code.addLine(TabbedLine(ShortComment("Declare StateFunctions map")));
697 code.addLine(TabbedLine(Declare(SpecNaming.StateFunctions, "*"
698 + SpecNaming.StateFunctionsInst)));
701 // StateFunction for interface
702 for (File file : interfaceListMap.keySet()) {
703 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
704 for (InterfaceConstruct construct : list) {
705 String name = construct.getName();
706 code.addLine(TabbedLine(ShortComment("StateFunction for "
708 // stateFuncs = new StateFunctions(
709 code.addLine(TabbedLine(SpecNaming.StateFunctionsInst
710 + " = new " + SpecNaming.StateFunctions + "("));
711 // new NamedFunction(_ENQ_Transition_str, TRANSITION, (void*)
714 code.addLine(TabbedLine(
716 + SpecNaming.NamedFunction
718 + SpecNaming.AppendStr(name + "_"
719 + SpecNaming.Transition) + ", "
720 + SpecNaming.TransitionType + ", (void*) _"
721 + name + "_" + SpecNaming.Transition + "),", 2));
724 + SpecNaming.NamedFunction
726 + SpecNaming.AppendStr(name + "_"
727 + SpecNaming.PreCondition) + ", "
728 + SpecNaming.PreConditionType + ", (void*) ";
729 if (construct.preCondition.isEmpty()) {
730 line = line + SpecNaming.NullFunc + "),";
732 line = line + "_" + name + "_" + SpecNaming.PreCondition
735 code.addLine(TabbedLine(line, 2));
738 + SpecNaming.NamedFunction
740 + SpecNaming.AppendStr(name + "_"
741 + SpecNaming.PostCondition) + ", "
742 + SpecNaming.PostConditionType + ", (void*) ";
743 if (construct.postCondition.isEmpty()) {
744 line = line + SpecNaming.NullFunc + "),";
746 line = line + "_" + name + "_" + SpecNaming.PostCondition
749 code.addLine(TabbedLine(line, 2));
752 + SpecNaming.NamedFunction
754 + SpecNaming.AppendStr(name + "_"
755 + SpecNaming.PrintValue) + ", "
756 + SpecNaming.PrintValueType + ", (void*) ";
757 if (construct.print.isEmpty()) {
758 line = line + SpecNaming.NullFunc + ")";
760 line = line + "_" + name + "_" + SpecNaming.PrintValue
763 code.addLine(TabbedLine(line, 2));
764 code.addLine(TabbedLine(");"));
766 // init->addInterfaceFunctions(_ENQ_str, stateFuncs);
767 code.addLine(TabbedLine(SpecNaming.AnnoInitInst
769 + SpecNaming.AddInterfaceFunctions
770 + Brace(SpecNaming.AppendStr(name) + ", "
771 + SpecNaming.StateFunctionsInst) + ";"));
776 // Create and instrument with the INIT annotation
777 code.addLine(TabbedLine(ShortComment("Create and instrument with the INIT annotation")));
778 // cdsannotate(SPEC_ANALYSIS, new SpecAnnotation(INIT, init));
779 code.addLine(TabbedLine(SpecNaming.CDSAnnotateFunc
780 + Brace(SpecNaming.SPEC_ANALYSIS
782 + SpecNaming.SpecAnnotation
783 + Brace(SpecNaming.AnnoTypeInit + ", "
784 + SpecNaming.AnnoInitInst)) + ";"));
794 * This function generates a list of lines that initialize the fields of the
795 * global state struct. See below.
800 * StateStruct *state = (StateStruct*) _M->state;
802 * IntList * q = state->q;
807 * In this example, _M --> methodInst, state --> inst.
815 * The global state construct
816 * @return The generated code
818 public static Code GenerateStateFieldsInitialization(String methodInst,
819 String inst, GlobalConstruct construct) {
820 Code res = new Code();
821 res.addLine(ShortComment("Initialize " + SpecNaming.StateStruct
823 res.addLine(DeclareDefine(SpecNaming.StateStruct, "*" + inst, "("
824 + SpecNaming.StateStruct + "*) " + methodInst + "->state"));
825 for (VariableDeclaration decl : construct.declState) {
826 res.addLine(DeclareDefine(decl.type, decl.name, inst + "->"
834 * This function generates a list of lines that initialize the fields of a
835 * specific interface struct. See below.
840 * ENQ *info = (ENQ*) _M->value;
842 * IntList * q = info->q;
847 * In this example, ENQ --> structType, _M --> methodInst, info --> inst
855 * The corresponding interface construct
856 * @return The generated code
858 public static Code GenerateInterfaceFieldsInitialization(String methodInst,
859 String inst, InterfaceConstruct construct) {
860 Code res = new Code();
861 String name = construct.getName();
862 res.addLine(ShortComment("Initialize fields for " + name));
863 // The very first assignment "
864 res.addLine(DeclareDefine(name, "*" + inst, "(" + name + "*) "
865 + methodInst + "->" + SpecNaming.MethodValueField));
866 // Don't leave out the RET field
867 if (!construct.getFunctionHeader().isReturnVoid()) {
868 res.addLine(DeclareDefine(construct.getFunctionHeader().returnType,
869 SpecNaming.RET, inst + "->" + SpecNaming.RET));
872 for (VariableDeclaration decl : construct.getFunctionHeader().args) {
873 res.addLine(DeclareDefine(decl.type, decl.name, inst + "->"
881 * This function generates the code to be inserted right after the ordering
882 * point construct (instrumentation code)
886 * The corresponding ordering point construct
887 * @return The generated code
889 public static Code Generate4OPConstruct(OPConstruct construct) {
890 Code code = new Code();
891 String curLine = construct.annotation;
892 String label = construct.label;
893 String prefixTabs = curLine.substring(0, curLine.indexOf("/**"));
894 if (!construct.condition.equals("true")) {
895 code.addLine(prefixTabs + "if (" + construct.condition + ")");
896 prefixTabs = prefixTabs + "\t";
899 switch (construct.type) {
901 code.addLine(prefixTabs + SpecNaming.CreateOPDefineAnnoFunc + "();");
904 code.addLine(prefixTabs + SpecNaming.CreatePotentialOPAnnoFunc
905 + "(" + SpecNaming.AppendStr(label) + ");");
908 code.addLine(prefixTabs + SpecNaming.CreateOPCheckAnnoFunc + "("
909 + SpecNaming.AppendStr(label) + ");");
912 code.addLine(prefixTabs + SpecNaming.CreateOPClearAnnoFunc + "();");
915 code.addLine(prefixTabs + SpecNaming.CreateOPClearDefineAnnoFunc
926 * This function generates the code to be inserted right after the entry
927 * construct (instrumentation code)
931 * The corresponding entry construct
934 public static Code Generate4Entry(EntryConstruct construct) {
935 Code res = new Code();
936 String curLine = construct.annotation;
937 String prefixTabs = curLine.substring(0, curLine.indexOf("/**"));
938 // _createInitAnnotation();
939 res.addLine(prefixTabs + SpecNaming.CreateInitAnnoFunc + "();");
945 * This function generates the code to be inserted right after the "@Define"
946 * construct (instrumentation code)
950 * The corresponding entry construct
953 public static Code Generate4Define(DefineConstruct construct) {
954 Code code = new Code();
956 code.addLine("/********** User-defined code in annotation (BEGIN) **********/");
957 code.addLines(construct.code);
958 code.addLine("/********** User-defined code in annotation (END) **********/");
964 * This function generates the new interface wrapper code to be inserted
965 * right after the end of the interface definition
969 * The corresponding interface construct
970 * @return The generated code
972 public static Code GenerateInterfaceWrapper(InterfaceConstruct construct) {
973 Code code = new Code();
975 String name = construct.getName();
976 String beginLine = construct.getFunctionHeader().getHeaderLine();
977 Pattern regexpSpace = Pattern.compile("^(\\s*)\\S.*$");
978 Matcher matcherSpace = regexpSpace.matcher(beginLine);
979 String prefixTabs = "";
980 if (matcherSpace.find())
981 prefixTabs = matcherSpace.group(1);
983 // Add one line to separate
985 code.addLine(prefixTabs
986 + ShortComment("Generated wrapper interface for " + name));
987 if (beginLine.indexOf('{') == -1) { // We need to add the '{' to the end
989 code.addLine(beginLine + " {");
991 code.addLine(beginLine);
993 // Instrument with the INTERFACE_BEGIN annotations
994 code.addLine(prefixTabs
996 + ShortComment("Instrument with the INTERFACE_BEGIN annotation"));
997 // CAnnoInterfaceInfo info = _createInterfaceBeginAnnotation(_DEQ_str);
998 code.addLine(prefixTabs
1000 + DeclareDefine(SpecNaming.AnnoInterfaceInfo, "*"
1001 + SpecNaming.AnnoInterfaceInfoInst,
1002 SpecNaming.CreateInterfaceBeginAnnoFunc
1003 + Brace(SpecNaming.AppendStr(name))));
1004 // Call the actual function
1005 code.addLine(prefixTabs + "\t"
1006 + ShortComment("Call the actual function"));
1007 // bool RET = dequeue_ORIGINAL__(q, retVal, reclaimNode);
1008 code.addLine(prefixTabs + "\t"
1009 + construct.getFunctionHeader().getRenamedCall() + ";");
1012 // Initialize the value struct
1013 code.addLine(prefixTabs + "\t"
1014 + ShortComment("Initialize the value struct"));
1015 // The very first assignment "
1016 code.addLine(prefixTabs
1018 + DeclareDefine(name, "*" + SpecNaming.InterfaceValueInst,
1019 SpecNaming.New + Brace(name)));
1020 // Don't leave out the RET field
1021 if (!construct.getFunctionHeader().isReturnVoid())
1022 code.addLine(prefixTabs
1024 + AssignToPtr(SpecNaming.InterfaceValueInst,
1025 SpecNaming.RET, SpecNaming.RET));
1027 for (VariableDeclaration decl : construct.getFunctionHeader().args)
1028 code.addLine(prefixTabs
1030 + AssignToPtr(SpecNaming.InterfaceValueInst, decl.name,
1034 // Store the value info into the current MethodCall
1035 // _setInterfaceBeginAnnotationValue(info, value);
1036 code.addLine(prefixTabs
1038 + ShortComment("Store the value info into the current MethodCall"));
1039 code.addLine(prefixTabs
1041 + SpecNaming.SetInterfaceBeginAnnoValueFunc
1042 + Brace(SpecNaming.AnnoInterfaceInfoInst + ", "
1043 + SpecNaming.InterfaceValueInst) + ";");
1046 // Return if necessary
1047 if (!construct.getFunctionHeader().isReturnVoid())
1048 code.addLine(prefixTabs + "\treturn " + SpecNaming.RET + ";");
1049 code.addLine(prefixTabs + "}");
1056 * Write a list of lines (as the whole of the file) to a file ---
1057 * newFileName. If that file does not exist, we create that file and then
1061 * @param newFileName
1062 * The name of the file to be written
1064 * The list of lines that as a whole become the content of the
1067 public static void write2File(String newFileName, ArrayList<String> content) {
1068 File newFile = new File(newFileName);
1069 newFile.getParentFile().mkdirs();
1070 if (!newFile.exists()) {
1072 newFile.createNewFile();
1073 } catch (IOException e) {
1074 e.printStackTrace();
1077 BufferedWriter bw = null;
1079 bw = new BufferedWriter(new FileWriter(newFile));
1080 for (int i = 0; i < content.size(); i++) {
1081 bw.write(content.get(i) + "\n");
1084 } catch (IOException e) {
1085 e.printStackTrace();
1090 } catch (IOException e) {
1091 e.printStackTrace();