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.EntryConstruct;
16 import edu.uci.eecs.specExtraction.FunctionHeader;
17 import edu.uci.eecs.specExtraction.GlobalConstruct;
18 import edu.uci.eecs.specExtraction.InterfaceConstruct;
19 import edu.uci.eecs.specExtraction.OPConstruct;
20 import edu.uci.eecs.specExtraction.SpecExtractor;
21 import edu.uci.eecs.specExtraction.SpecNaming;
22 import edu.uci.eecs.specExtraction.VariableDeclaration;
26 * Some utility functions for generating specification checking code.
32 public class CodeGeneratorUtils {
34 public static void PrintCode(ArrayList<String> code) {
35 for (int i = 0; i < code.size(); i++) {
36 System.out.println(code.get(i));
40 public static String Comment(String comment) {
41 return "/** " + comment + " */";
44 public static String ShortComment(String comment) {
45 return "// " + comment;
48 public static String IncludeHeader(String header) {
49 return "#include " + header;
52 public static String Brace(String val) {
53 return "(" + val + ")";
56 public static String Quote(String val) {
57 return "\"" + val + "\"";
60 public static String Assign(String varName, String val) {
61 return varName + " = " + val + ";";
64 public static String AssignToPtr(String structName, String field, String val) {
65 return structName + "->" + field + " = " + val + ";";
68 public static String Declare(String type, String name) {
69 return type + " " + name + ";";
72 public static String Declare(VariableDeclaration varDecl) {
73 return Declare(varDecl.type, varDecl.name);
76 public static String DeclareDefine(String type, String var, String val) {
77 return type + " " + var + " = " + val + ";";
82 * Insert a number of tabs at the beginning of the line.
88 * The number of tabs to be inserted
89 * @return A line that starts with the specific inserted tabs
91 public static String TabbedLine(String line, int tabCnt) {
93 for (int i = 0; i < tabCnt; i++)
101 * Insert a tab at the beginning of the line.
106 * @return A line that starts with one inserted tab
108 public static String TabbedLine(String line) {
114 * This function generates the code for the header file that our
115 * specification generates automatically --- cdsspec-generated.h.
119 * The SpecExtractor that contains the extracted information
120 * @return The generated code
122 public static Code GenerateCDSSpecHeaderFile(SpecExtractor extractor) {
123 HashSet<String> headerFiles = extractor.headerFiles;
124 GlobalConstruct globalConstruct = extractor.getGlobalConstruct();
125 HashMap<File, ArrayList<InterfaceConstruct>> interfaceListMap = extractor.interfaceListMap;
126 HashSet<String> OPLabelSet = extractor.OPLabelSet;
128 Code code = new Code();
130 // Add auto-generated comments
132 code.addLine(TabbedLine("This is a header file auto-generated by CDSSpec compiler; together, CDSSpec"));
133 code.addLine(TabbedLine("compiler should have generated the accompanying implementation file that"));
134 code.addLine(TabbedLine("implements the some functions declared in this file. In order to instrument"));
135 code.addLine(TabbedLine("your benchmark for CDSSpec checker to check, you should include this header"));
136 code.addLine(TabbedLine("file in every file you use an CDSSpec annotation. Note that it should be"));
137 code.addLine(TabbedLine("placed in the end of all other header files. Currently we require a C++"));
138 code.addLine(TabbedLine("compiler that supports C++11."));
142 code.addLine("#ifndef _"
143 + SpecNaming.CDSSpecGeneratedName.toUpperCase().replace('-',
145 code.addLine("#define _"
146 + SpecNaming.CDSSpecGeneratedName.toUpperCase().replace('-',
150 // System included headers
151 code.addLine(ShortComment("System included headers go here"));
152 for (String header : SpecNaming.includedHeadersList) {
153 code.addLine(IncludeHeader(header));
157 // Users included headers
158 code.addLine(ShortComment("User included headers go here"));
159 for (String header : headerFiles) {
160 code.addLine(IncludeHeader(header));
164 code.addLine("using namespace std;");
168 code.addLine(ShortComment("Declaration of some c-strings (CSTR)"));
169 code.addLine(ShortComment("A special empty string"));
170 code.addLine(Declare("extern " + SpecNaming.CString,
171 SpecNaming.EmptyCString));
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 // Commutativity rule strings
187 code.addLine(ShortComment("Commutativity rule strings"));
188 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
189 code.addLine(Declare("extern " + SpecNaming.CString,
190 SpecNaming.AppendStr(SpecNaming.Commutativity + i)));
194 // Ordering points label strings
195 code.addLine(ShortComment("Ordering points label strings"));
196 for (String label : OPLabelSet) {
197 code.addLine(Declare("extern " + SpecNaming.CString,
198 SpecNaming.AppendStr(label)));
202 // Special function name strings
203 code.addLine(ShortComment("Special function name strings"));
204 code.addLine(Declare("extern " + SpecNaming.CString,
205 SpecNaming.AppendStr(SpecNaming.InitalState)));
206 code.addLine(Declare("extern " + SpecNaming.CString,
207 SpecNaming.AppendStr(SpecNaming.CopyState)));
208 code.addLine(Declare("extern " + SpecNaming.CString,
209 SpecNaming.AppendStr(SpecNaming.FinalState)));
210 code.addLine(Declare("extern " + SpecNaming.CString,
211 SpecNaming.AppendStr(SpecNaming.PrintState)));
214 // Interface name strings
215 for (File file : interfaceListMap.keySet()) {
216 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
217 for (InterfaceConstruct construct : list) {
218 String name = construct.getName();
219 code.addLine(ShortComment(name + " function strings"));
221 String tmpFunc = name + "_" + SpecNaming.Transition;
222 code.addLine(Declare("extern " + SpecNaming.CString,
223 SpecNaming.AppendStr(tmpFunc)));
225 tmpFunc = name + "_" + SpecNaming.PreCondition;
226 code.addLine(Declare("extern " + SpecNaming.CString,
227 SpecNaming.AppendStr(tmpFunc)));
229 tmpFunc = name + "_" + SpecNaming.SideEffect;
230 code.addLine(Declare("extern " + SpecNaming.CString,
231 SpecNaming.AppendStr(tmpFunc)));
233 tmpFunc = name + "_" + SpecNaming.PostCondition;
234 code.addLine(Declare("extern " + SpecNaming.CString,
235 SpecNaming.AppendStr(tmpFunc)));
237 tmpFunc = name + "_" + SpecNaming.PrintValue;
238 code.addLine(Declare("extern " + SpecNaming.CString,
239 SpecNaming.AppendStr(tmpFunc)));
244 // Declare customized StateStruct
245 code.addLine(ShortComment("Declare customized StateStruct"));
246 code.addLine("typedef struct " + SpecNaming.StateStruct + " {");
247 for (VariableDeclaration decl : globalConstruct.declState) {
248 code.addLine(TabbedLine(Declare(decl)));
251 code.addLine(TabbedLine("SNAPSHOTALLOC"));
252 code.addLine("} " + SpecNaming.StateStruct + ";");
255 // Declare customized value struct
256 for (File file : interfaceListMap.keySet()) {
257 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
258 for (InterfaceConstruct construct : list) {
259 // Declare custom value struct for the interface
260 String name = construct.getName();
261 code.addLine(ShortComment("Declare custom value struct for "
263 code.addLine("typedef struct " + name + " {");
264 FunctionHeader funcHeader = construct.getFunctionHeader();
266 if (!funcHeader.returnType.equals("void"))
267 code.addLine(TabbedLine(Declare(funcHeader.returnType,
270 for (VariableDeclaration decl : funcHeader.args) {
271 code.addLine(TabbedLine(Declare(decl)));
273 code.addLine("} " + name + ";");
279 code.addLine(ShortComment("Declare @" + SpecNaming.InitalState));
280 code.addLine("void _" + SpecNaming.InitalState.toLowerCase() + "("
281 + SpecNaming.Method + " " + SpecNaming.Method1 + ");");
284 code.addLine(ShortComment("Declare @" + SpecNaming.CopyState));
285 code.addLine("void _" + SpecNaming.CopyState.toLowerCase() + "("
286 + SpecNaming.Method + " " + "dest, " + SpecNaming.Method
290 code.addLine(ShortComment("Declare @" + SpecNaming.PrintState));
291 if (!globalConstruct.printState.isEmpty()) {
292 code.addLine("void _" + SpecNaming.PrintState.toLowerCase() + "("
293 + SpecNaming.Method + " " + SpecNaming.Method1 + ");");
297 // Declare @Commutativity
298 code.addLine(ShortComment("Declare commutativity checking functions"));
299 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
300 code.addLine("bool _check" + SpecNaming.Commutativity + i + "("
301 + SpecNaming.Method + " m1, " + SpecNaming.Method + " m2);");
305 // Declare customized interface functions
306 for (File file : interfaceListMap.keySet()) {
307 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
308 for (InterfaceConstruct construct : list) {
309 // Declare interface functions
310 String name = construct.getName();
311 code.addLine("/********** " + name
312 + " functions **********/");
313 // Declare @Transition for INTERFACE
314 code.addLine(ShortComment("Declare @" + SpecNaming.Transition
316 code.addLine("void _" + name + "_" + SpecNaming.Transition
317 + "(" + SpecNaming.Method + " " + SpecNaming.Method1
318 + ", " + SpecNaming.Method + " " + SpecNaming.Method2
321 // Declare @PreCondition
322 if (!construct.preCondition.isEmpty()) {
323 code.addLine(ShortComment("Declare @"
324 + SpecNaming.PreCondition + " for " + name));
325 code.addLine("bool _" + name + "_"
326 + SpecNaming.PreCondition + "(" + SpecNaming.Method
327 + " " + SpecNaming.Method1 + ");");
330 // Declare @SideEffect
331 if (!construct.sideEffect.isEmpty()) {
332 code.addLine(ShortComment("Declare @"
333 + SpecNaming.SideEffect + " for " + name));
334 code.addLine("void _" + name + "_" + SpecNaming.SideEffect
335 + "(" + SpecNaming.Method + " "
336 + SpecNaming.Method1 + ");");
339 // Declare @PostCondition
340 if (!construct.postCondition.isEmpty()) {
341 code.addLine(ShortComment("Declare @"
342 + SpecNaming.PostCondition + " for " + name));
343 code.addLine("bool _" + name + "_"
344 + SpecNaming.PostCondition + "("
345 + SpecNaming.Method + " " + SpecNaming.Method1
350 if (!construct.print.isEmpty()) {
351 code.addLine(ShortComment("Declare @"
352 + SpecNaming.PrintValue + " for " + name));
353 code.addLine("void _" + name + "_" + SpecNaming.PrintValue
354 + "(" + SpecNaming.Method + " "
355 + SpecNaming.Method1 + ");");
361 // Declare INIT annotation instrumentation function
362 code.addLine(ShortComment("Declare INIT annotation instrumentation function"));
363 code.addLine("void _createInitAnnotation();");
365 code.addLine("#endif");
372 * This function generates the code for the CPP file that our specification
373 * generates automatically --- cdsspec-generated.cc.
377 * The SpecExtractor that contains the extracted information
378 * @return The generated code
380 public static Code GenerateCDSSpecCPPFile(SpecExtractor extractor) {
381 GlobalConstruct globalConstruct = extractor.getGlobalConstruct();
382 HashMap<File, ArrayList<InterfaceConstruct>> interfaceListMap = extractor.interfaceListMap;
383 HashSet<String> OPLabelSet = extractor.OPLabelSet;
385 Code code = new Code();
388 // Add auto-generated comments
390 code.addLine(TabbedLine("This is an implementation file auto-generated by CDSSpec compiler to"));
391 code.addLine(TabbedLine("instrument your benchmark for CDSSpec checker to check. Currently we require"));
392 code.addLine(TabbedLine("a C++ compiler that supports C++11."));
396 code.addLine("#include " + SpecNaming.CDSSpecGeneratedHeader);
400 code.addLine(ShortComment("Definition of some c-strings (CSTR)"));
401 code.addLine(ShortComment("A special empty string"));
402 code.addLine(DeclareDefine(SpecNaming.CString, SpecNaming.EmptyCString,
406 // Interface name strings
407 code.addLine(ShortComment("Interface name strings"));
408 for (File file : interfaceListMap.keySet()) {
409 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
410 for (InterfaceConstruct construct : list) {
411 String name = construct.getName();
412 code.addLine(DeclareDefine(SpecNaming.CString,
413 SpecNaming.AppendStr(name), Quote(name)));
418 // Commutativity rule strings
419 code.addLine(ShortComment("Commutativity rule strings"));
420 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
421 CommutativityRule rule = globalConstruct.commutativityRules
423 code.addLine(DeclareDefine(SpecNaming.CString,
424 SpecNaming.AppendStr(SpecNaming.Commutativity + i),
425 Quote(rule.toString())));
429 // Ordering points label strings
430 code.addLine(ShortComment("Ordering points label strings"));
431 for (String label : OPLabelSet) {
432 code.addLine(DeclareDefine(SpecNaming.CString,
433 SpecNaming.AppendStr(label), Quote(label)));
437 // Special function name strings
438 code.addLine(ShortComment("Special function name strings"));
439 code.addLine(DeclareDefine(SpecNaming.CString,
440 SpecNaming.AppendStr(SpecNaming.InitalState), Quote("_"
441 + SpecNaming.InitalState.toLowerCase())));
442 code.addLine(DeclareDefine(SpecNaming.CString,
443 SpecNaming.AppendStr(SpecNaming.CopyState), Quote("_"
444 + SpecNaming.CopyState.toLowerCase())));
445 code.addLine(DeclareDefine(SpecNaming.CString,
446 SpecNaming.AppendStr(SpecNaming.FinalState), Quote("_"
447 + SpecNaming.FinalState.toLowerCase())));
448 code.addLine(DeclareDefine(SpecNaming.CString,
449 SpecNaming.AppendStr(SpecNaming.PrintState), Quote("_"
450 + SpecNaming.PrintState.toLowerCase())));
453 // Interface name strings
454 for (File file : interfaceListMap.keySet()) {
455 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
456 for (InterfaceConstruct construct : list) {
457 String name = construct.getName();
458 code.addLine(ShortComment(name + " function strings"));
460 String tmpFunc = name + "_" + SpecNaming.Transition;
461 code.addLine(DeclareDefine(SpecNaming.CString,
462 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
464 tmpFunc = name + "_" + SpecNaming.PreCondition;
465 if (!construct.preCondition.isEmpty())
466 code.addLine(DeclareDefine(SpecNaming.CString,
467 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
469 code.addLine(DeclareDefine(SpecNaming.CString,
470 SpecNaming.AppendStr(tmpFunc),
471 SpecNaming.EmptyCString));
473 tmpFunc = name + "_" + SpecNaming.SideEffect;
474 if (!construct.sideEffect.isEmpty())
475 code.addLine(DeclareDefine(SpecNaming.CString,
476 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
478 code.addLine(DeclareDefine(SpecNaming.CString,
479 SpecNaming.AppendStr(tmpFunc),
480 SpecNaming.EmptyCString));
482 tmpFunc = name + "_" + SpecNaming.PostCondition;
483 if (!construct.postCondition.isEmpty())
484 code.addLine(DeclareDefine(SpecNaming.CString,
485 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
487 code.addLine(DeclareDefine(SpecNaming.CString,
488 SpecNaming.AppendStr(tmpFunc),
489 SpecNaming.EmptyCString));
491 tmpFunc = name + "_" + SpecNaming.PrintValue;
492 if (!construct.print.isEmpty())
493 code.addLine(DeclareDefine(SpecNaming.CString,
494 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
496 code.addLine(DeclareDefine(SpecNaming.CString,
497 SpecNaming.AppendStr(tmpFunc),
498 SpecNaming.EmptyCString));
504 code.addLine(ShortComment("Define @" + SpecNaming.InitalState));
505 code.addLine("void _" + SpecNaming.InitalState.toLowerCase() + "("
506 + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
507 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
508 + SpecNaming.StateInst, "new " + SpecNaming.StateStruct)));
510 for (VariableDeclaration decl : globalConstruct.declState) {
511 code.addLine(TabbedLine("#define " + decl.name + " "
512 + SpecNaming.StateInst + "->" + decl.name));
514 code.addLine(TabbedLine(ShortComment("User-defined intial state code")));
515 // Align the code with one tab
516 globalConstruct.initState.align(1);
517 code.addLines(globalConstruct.initState);
519 for (VariableDeclaration decl : globalConstruct.declState) {
520 code.addLine(TabbedLine("#undef " + decl.name));
523 code.addLine(TabbedLine(AssignToPtr(SpecNaming.Method1,
524 SpecNaming.StateInst, SpecNaming.StateInst)));
529 code.addLine(ShortComment("Define @" + SpecNaming.CopyState));
530 code.addLine("void _" + SpecNaming.CopyState.toLowerCase() + "("
531 + SpecNaming.Method + " " + "dest, " + SpecNaming.Method
533 // StateStruct *OLD = (StateStruct*) src->state;
534 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
535 + SpecNaming.OldStateInst, Brace(SpecNaming.StateStruct + "*")
536 + " src->" + SpecNaming.StateInst)));
537 // StateStruct *NEW = new StateStruct;
538 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
539 + SpecNaming.NewStateInst, "new " + SpecNaming.StateStruct)));
540 if (!globalConstruct.autoGenCopy)
541 code.addLine(TabbedLine(ShortComment("User-defined state copy statements")));
543 // Auto-generated the copy function
544 code.addLine(TabbedLine(ShortComment("Auto-generated state copy statements")));
545 globalConstruct.copyState.align(1);
546 code.addLines(globalConstruct.copyState);
548 code.addLine(TabbedLine(AssignToPtr("dest", SpecNaming.StateInst,
549 SpecNaming.NewStateInst)));
554 if (!globalConstruct.printState.isEmpty()) {
555 code.addLine(ShortComment("Define @" + SpecNaming.PrintState));
556 code.addLine("void _" + SpecNaming.PrintState.toLowerCase() + "("
557 + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
559 // Initialize state struct fields
560 Code fieldsInit = GenerateStateFieldsInitialization(
561 SpecNaming.Method1, SpecNaming.StateInst, globalConstruct);
563 code.addLines(fieldsInit);
565 code.addLine(TabbedLine(ShortComment("Execute the print-out")));
566 // Align the code with one tab
567 globalConstruct.printState.align(1);
568 code.addLines(globalConstruct.printState);
573 // Define @Commutativity
574 code.addLine(ShortComment("Define commutativity checking functions"));
575 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
576 CommutativityRule rule = globalConstruct.commutativityRules
578 code.addLine("bool _check" + SpecNaming.Commutativity + i + "("
579 + SpecNaming.Method + " m1, " + SpecNaming.Method
581 // if (m1->name == _ENQ_str && m2->name == _DEQ_str) {
582 code.addLine(TabbedLine("if (m1->name == "
583 + SpecNaming.AppendStr(rule.method1) + " && m2->name == "
584 + SpecNaming.AppendStr(rule.method2) + ") {"));
585 // Initialize M1 & M2 in commutativity rule
586 // e.g. ENQ *M1 = (ENQ*) m1->value;
587 code.addLine(TabbedLine(
588 DeclareDefine(rule.method1, "*M1", "(" + rule.method1
589 + "*) m1->value"), 2));
590 code.addLine(TabbedLine(
591 DeclareDefine(rule.method2, "*M2", "(" + rule.method2
592 + "*) m2->value"), 2));
593 code.addLine(TabbedLine("return " + rule.condition + ";", 2));
594 code.addLine(TabbedLine("}"));
595 code.addLine(TabbedLine("return false;"));
601 // Define customized interface functions
602 for (File file : interfaceListMap.keySet()) {
603 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
604 for (InterfaceConstruct construct : list) {
605 Code fieldsInit = null;
607 // Define interface functions
608 String name = construct.getName();
609 code.addLine("/********** " + name
610 + " functions **********/");
611 // Define @Transition for INTERFACE
612 code.addLine(ShortComment("Define @" + SpecNaming.Transition
614 code.addLine("void _" + name + "_" + SpecNaming.Transition
615 + "(" + SpecNaming.Method + " " + SpecNaming.Method1
616 + ", " + SpecNaming.Method + " " + SpecNaming.Method2
619 // Initialize value struct fields
620 fieldsInit = GenerateInterfaceFieldsInitialization(
621 SpecNaming.Method2, "value", construct);
623 code.addLines(fieldsInit);
625 construct.transition.align(1);
626 code.addLine(TabbedLine(ShortComment("Execute Transition")));
627 code.addLines(construct.transition);
632 // Define @PreCondition
633 if (!construct.preCondition.isEmpty()) {
634 code.addLine(ShortComment("Define @"
635 + SpecNaming.PreCondition + " for " + name));
636 code.addLine("bool _" + name + "_"
637 + SpecNaming.PreCondition + "(" + SpecNaming.Method
638 + " " + SpecNaming.Method1 + ") {");
640 // Initialize value struct fields
641 fieldsInit = GenerateInterfaceFieldsInitialization(
642 SpecNaming.Method1, "value", construct);
644 code.addLines(fieldsInit);
646 construct.preCondition.align(1);
647 code.addLine(TabbedLine(ShortComment("Execute PreCondition")));
648 code.addLines(construct.preCondition);
654 // Define @SideEffect
655 if (!construct.sideEffect.isEmpty()) {
656 code.addLine(ShortComment("Define @"
657 + SpecNaming.SideEffect + " for " + name));
658 code.addLine("void _" + name + "_" + SpecNaming.SideEffect
659 + "(" + SpecNaming.Method + " "
660 + SpecNaming.Method1 + ") {");
662 // Initialize value struct fields
663 fieldsInit = GenerateInterfaceFieldsInitialization(
664 SpecNaming.Method1, "value", construct);
666 code.addLines(fieldsInit);
668 construct.sideEffect.align(1);
669 code.addLine(TabbedLine(ShortComment("Execute SideEffect")));
670 code.addLines(construct.sideEffect);
675 // Define @PostCondition
676 if (!construct.postCondition.isEmpty()) {
677 code.addLine(ShortComment("Define @"
678 + SpecNaming.PostCondition + " for " + name));
679 code.addLine("bool _" + name + "_"
680 + SpecNaming.PostCondition + "("
681 + SpecNaming.Method + " " + SpecNaming.Method1
684 // Initialize value struct fields
685 fieldsInit = GenerateInterfaceFieldsInitialization(
686 SpecNaming.Method1, "value", construct);
688 code.addLines(fieldsInit);
690 construct.postCondition.align(1);
691 code.addLine(TabbedLine(ShortComment("Execute PostCondition")));
692 code.addLines(construct.postCondition);
698 if (!construct.print.isEmpty()) {
699 code.addLine(ShortComment("Define @"
700 + SpecNaming.PrintValue + " for " + name));
701 code.addLine("void _" + name + "_" + SpecNaming.PrintValue
702 + "(" + SpecNaming.Method + " "
703 + SpecNaming.Method1 + ") {");
704 // Initialize value struct fields
705 fieldsInit = GenerateInterfaceFieldsInitialization(
706 SpecNaming.Method1, "value", construct);
708 code.addLines(fieldsInit);
710 construct.print.align(1);
711 code.addLine(TabbedLine(ShortComment("Execute Print")));
712 code.addLines(construct.print);
720 // Define INIT annotation instrumentation function
721 code.addLine(ShortComment("Define INIT annotation instrumentation function"));
722 code.addLine("void _createInitAnnotation() {");
724 // Init commutativity rules
725 code.addLine(TabbedLine(ShortComment("Init commutativity rules")));
726 code.addLine(TabbedLine(DeclareDefine("int",
727 SpecNaming.CommutativityRuleSizeInst,
728 Integer.toString(globalConstruct.commutativityRules.size()))));
729 String tmp = SpecNaming.NewSize
730 + Brace(SpecNaming.CommutativityRule + ", sizeof"
731 + Brace(SpecNaming.CommutativityRule) + " * "
732 + SpecNaming.CommutativityRuleSizeInst);
733 code.addLine(TabbedLine(DeclareDefine(SpecNaming.CommutativityRule, "*"
734 + SpecNaming.CommutativityRuleInst, tmp)));
735 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
736 CommutativityRule rule = globalConstruct.commutativityRules
738 code.addLine(TabbedLine(ShortComment("Initialize commutativity rule ")
740 // new( &commuteRules[0] )CommutativityRule(_ENQ_str, _DEQ_str,
741 // _Commutativity1_str, _checkCommutativity1)
743 + Brace(" &" + SpecNaming.CommutativityRuleInst + "["
744 + (i - 1) + "] ") + SpecNaming.CommutativityRule
745 + "(" + SpecNaming.AppendStr(rule.method1) + ", "
746 + SpecNaming.AppendStr(rule.method2) + ", "
747 + SpecNaming.AppendStr(SpecNaming.Commutativity + i) + ", "
748 + "_check" + SpecNaming.Commutativity + i + ");";
749 code.addLine(TabbedLine(line));
752 // Initialize AnnoInit
753 code.addLine(TabbedLine(ShortComment("Initialize AnnoInit")));
754 // AnnoInit *init = new AnnoInit(
755 code.addLine(TabbedLine(SpecNaming.AnnoInit + " *"
756 + SpecNaming.AnnoInitInst + " = new " + SpecNaming.AnnoInit
758 // new NamedFunction(_Initial_str, INITIAL, (void*) _initial),
759 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
760 + SpecNaming.AppendStr(SpecNaming.InitalState) + ", "
761 + SpecNaming.InitalState.toUpperCase() + ", " + "(void*) _"
762 + SpecNaming.InitalState.toLowerCase() + "),", 2));
763 // new NamedFunction(_Final_str, FINAL, (void*) NULL_FUNC),
764 line = "new " + SpecNaming.NamedFunction + "("
765 + SpecNaming.AppendStr(SpecNaming.FinalState) + ", "
766 + SpecNaming.FinalState.toUpperCase() + ", " + "(void*) ";
767 if (globalConstruct.finalState.isEmpty()) {
768 line = line + SpecNaming.NullFunc + "),";
770 line = line + "_" + SpecNaming.FinalState.toUpperCase();
772 code.addLine(TabbedLine(line, 2));
773 // new NamedFunction(_Copy_str, COPY, (void*) _copy),
774 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
775 + SpecNaming.AppendStr(SpecNaming.CopyState) + ", "
776 + SpecNaming.CopyState.toUpperCase() + ", " + "(void*) _"
777 + SpecNaming.CopyState.toLowerCase() + "),", 2));
778 // new NamedFunction(_Print_str, PRINT_STATE, (void*) _print),
779 line = "new " + SpecNaming.NamedFunction + "("
780 + SpecNaming.AppendStr(SpecNaming.PrintState) + ", "
781 + SpecNaming.PrintStateType + ", " + "(void*)";
782 if (globalConstruct.printState.isEmpty()) {
783 line = line + SpecNaming.NullFunc + "),";
785 line = line + "_" + SpecNaming.PrintState.toLowerCase() + "),";
787 code.addLine(TabbedLine(line, 2));
788 // commuteRules, CommuteRuleSize);
789 code.addLine(TabbedLine(SpecNaming.CommutativityRuleInst + ", "
790 + SpecNaming.CommutativityRuleSizeInst + ");", 2));
793 // Declare StateFunctions map
794 code.addLine(TabbedLine(ShortComment("Declare StateFunctions map")));
795 code.addLine(TabbedLine(Declare(SpecNaming.StateFunctions, "*"
796 + SpecNaming.StateFunctionsInst)));
799 // StateFunction for interface
800 for (File file : interfaceListMap.keySet()) {
801 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
802 for (InterfaceConstruct construct : list) {
803 String name = construct.getName();
804 code.addLine(TabbedLine(ShortComment("StateFunction for "
806 // stateFuncs = new StateFunctions(
807 code.addLine(TabbedLine(SpecNaming.StateFunctionsInst
808 + " = new " + SpecNaming.StateFunctions + "("));
809 // new NamedFunction(_ENQ_Transition_str, TRANSITION, (void*)
812 code.addLine(TabbedLine(
814 + SpecNaming.NamedFunction
816 + SpecNaming.AppendStr(name + "_"
817 + SpecNaming.Transition) + ", "
818 + SpecNaming.TransitionType + ", (void*) _"
819 + name + "_" + SpecNaming.Transition + "),", 2));
822 + SpecNaming.NamedFunction
824 + SpecNaming.AppendStr(name + "_"
825 + SpecNaming.PreCondition) + ", "
826 + SpecNaming.PreConditionType + ", (void*) ";
827 if (construct.preCondition.isEmpty()) {
828 line = line + SpecNaming.NullFunc + "),";
830 line = line + "_" + name + "_" + SpecNaming.PreCondition
833 code.addLine(TabbedLine(line, 2));
836 + SpecNaming.NamedFunction
838 + SpecNaming.AppendStr(name + "_"
839 + SpecNaming.SideEffect) + ", "
840 + SpecNaming.SideEffectType + ", (void*) ";
841 if (construct.sideEffect.isEmpty()) {
842 line = line + SpecNaming.NullFunc + "),";
844 line = line + "_" + name + "_" + SpecNaming.SideEffect
847 code.addLine(TabbedLine(line, 2));
850 + SpecNaming.NamedFunction
852 + SpecNaming.AppendStr(name + "_"
853 + SpecNaming.PostCondition) + ", "
854 + SpecNaming.PostConditionType + ", (void*) ";
855 if (construct.postCondition.isEmpty()) {
856 line = line + SpecNaming.NullFunc + "),";
858 line = line + "_" + name + "_" + SpecNaming.PostCondition
861 code.addLine(TabbedLine(line, 2));
864 + SpecNaming.NamedFunction
866 + SpecNaming.AppendStr(name + "_"
867 + SpecNaming.PrintValue) + ", "
868 + SpecNaming.PrintValueType + ", (void*) ";
869 if (construct.print.isEmpty()) {
870 line = line + SpecNaming.NullFunc + ")";
872 line = line + "_" + name + "_" + SpecNaming.PrintValue
875 code.addLine(TabbedLine(line, 2));
876 code.addLine(TabbedLine(");"));
878 // init->addInterfaceFunctions(_ENQ_str, stateFuncs);
879 code.addLine(TabbedLine(SpecNaming.AnnoInitInst
881 + SpecNaming.AddInterfaceFunctions
882 + Brace(SpecNaming.AppendStr(name) + ", "
883 + SpecNaming.StateFunctionsInst) + ";"));
888 // Create and instrument with the INIT annotation
889 code.addLine(TabbedLine(ShortComment("Create and instrument with the INIT annotation")));
890 // cdsannotate(SPEC_ANALYSIS, new SpecAnnotation(INIT, init));
891 code.addLine(TabbedLine(SpecNaming.CDSAnnotateFunc
892 + Brace(SpecNaming.SPEC_ANALYSIS
894 + SpecNaming.SpecAnnotation
895 + Brace(SpecNaming.AnnoTypeInit + ", "
896 + SpecNaming.AnnoInitInst)) + ";"));
906 * This function generates a list of lines that initialize the fields of the
907 * global state struct. See below.
912 * StateStruct *state = (StateStruct*) _M->state;
914 * IntList * q = state->q;
919 * In this example, _M --> methodInst, state --> inst.
927 * The global state construct
928 * @return The generated code
930 public static Code GenerateStateFieldsInitialization(String methodInst,
931 String inst, GlobalConstruct construct) {
932 Code res = new Code();
933 res.addLine(ShortComment("Initialize " + SpecNaming.StateStruct
935 res.addLine(DeclareDefine(SpecNaming.StateStruct, "*" + inst, "("
936 + SpecNaming.StateStruct + "*) " + methodInst + "->state"));
937 for (VariableDeclaration decl : construct.declState) {
938 res.addLine(DeclareDefine(decl.type, decl.name, inst + "->"
946 * This function generates a list of lines that initialize the fields of a
947 * specific interface struct. See below.
952 * ENQ *info = (ENQ*) _M->value;
954 * IntList * q = info->q;
959 * In this example, ENQ --> structType, _M --> methodInst, info --> inst
967 * The corresponding interface construct
968 * @return The generated code
970 public static Code GenerateInterfaceFieldsInitialization(String methodInst,
971 String inst, InterfaceConstruct construct) {
972 Code res = new Code();
973 String name = construct.getName();
974 res.addLine(ShortComment("Initialize fields for " + name));
975 // The very first assignment "
976 res.addLine(DeclareDefine(name, "*" + inst, "(" + name + "*) "
977 + methodInst + "->value"));
978 // Don't leave out the RET field
979 if (!construct.getFunctionHeader().isReturnVoid()) {
980 res.addLine(DeclareDefine(construct.getFunctionHeader().returnType,
981 SpecNaming.RET, "value->" + SpecNaming.RET));
984 for (VariableDeclaration decl : construct.getFunctionHeader().args) {
985 res.addLine(DeclareDefine(decl.type, decl.name, inst + "->"
993 * This function generates the code to be inserted right after the ordering
994 * point construct (instrumentation code)
998 * The corresponding ordering point construct
999 * @return The generated code
1001 public static Code Generate4OPConstruct(OPConstruct construct) {
1002 Code code = new Code();
1003 String curLine = construct.annotation;
1004 String label = construct.label;
1005 String prefixTabs = curLine.substring(0, curLine.indexOf("/**"));
1006 code.addLine(prefixTabs + "if (" + construct.condition + ")");
1007 switch (construct.type) {
1009 code.addLine(prefixTabs + "\t" + SpecNaming.CreateOPDefineAnnoFunc
1013 code.addLine(prefixTabs + "\t"
1014 + SpecNaming.CreatePotentialOPAnnoFunc + "("
1015 + SpecNaming.AppendStr(label) + ");");
1018 code.addLine(prefixTabs + "\t" + SpecNaming.CreateOPCheckAnnoFunc
1019 + "(" + SpecNaming.AppendStr(label) + ");");
1022 code.addLine(prefixTabs + "\t" + SpecNaming.CreateOPClearAnnoFunc
1026 code.addLine(prefixTabs + "\t"
1027 + SpecNaming.CreateOPClearDefineAnnoFunc + "();");
1037 * This function generates the code to be inserted right after the entry
1038 * construct (instrumentation code)
1042 * The corresponding entry construct
1045 public static Code Generate4Entry(EntryConstruct construct) {
1046 Code res = new Code();
1047 String curLine = construct.annotation;
1048 String prefixTabs = curLine.substring(0, curLine.indexOf("/**"));
1049 // _createInitAnnotation();
1050 res.addLine(prefixTabs + SpecNaming.CreateInitAnnoFunc + "();");
1056 * This function generates the new interface wrapper code to be inserted
1057 * right after the end of the interface definition
1061 * The corresponding interface construct
1062 * @return The generated code
1064 public static Code GenerateInterfaceWrapper(InterfaceConstruct construct) {
1065 Code code = new Code();
1067 String name = construct.getName();
1068 String beginLine = construct.getFunctionHeader().getHeaderLine();
1069 Pattern regexpSpace = Pattern.compile("^(\\s*)\\S.*$");
1070 Matcher matcherSpace = regexpSpace.matcher(beginLine);
1071 String prefixTabs = "";
1072 if (matcherSpace.find())
1073 prefixTabs = matcherSpace.group(1);
1075 // Add one line to separate
1077 code.addLine(prefixTabs
1078 + ShortComment("Generated wrapper interface for " + name));
1079 if (beginLine.indexOf('{') == -1) { // We need to add the '{' to the end
1081 code.addLine(beginLine + " {");
1083 code.addLine(beginLine);
1085 // Instrument with the INTERFACE_BEGIN annotation
1086 code.addLine(prefixTabs
1088 + ShortComment("Instrument with the INTERFACE_BEGIN annotation"));
1089 // AnnoInterfaceInfo *info = _createInterfaceBeginAnnotation(_DEQ_str);
1090 code.addLine(prefixTabs
1092 + DeclareDefine(SpecNaming.AnnoInterfaceInfo, "*"
1093 + SpecNaming.AnnoInterfaceInfoInst,
1094 SpecNaming.CreateInterfaceBeginAnnoFunc
1095 + Brace(SpecNaming.AppendStr(name))));
1096 // Call the actual function
1097 code.addLine(prefixTabs + "\t"
1098 + ShortComment("Call the actual function"));
1099 // bool RET = dequeue_ORIGINAL__(q, retVal, reclaimNode);
1100 code.addLine(prefixTabs + "\t"
1101 + construct.getFunctionHeader().getRenamedCall() + ";");
1104 // Initialize the value struct
1105 code.addLine(prefixTabs + "\t"
1106 + ShortComment("Initialize the value struct"));
1107 // The very first assignment "
1108 code.addLine(prefixTabs + "\t"
1109 + DeclareDefine(name, "*value", "new " + name));
1110 // Don't leave out the RET field
1111 if (!construct.getFunctionHeader().isReturnVoid())
1112 code.addLine(prefixTabs + "\t"
1113 + AssignToPtr("value", SpecNaming.RET, SpecNaming.RET));
1115 for (VariableDeclaration decl : construct.getFunctionHeader().args)
1116 code.addLine(prefixTabs + "\t"
1117 + AssignToPtr("value", decl.name, decl.name));
1120 // Store the value info into the current MethodCall
1121 code.addLine(prefixTabs
1123 + ShortComment("Store the value info into the current MethodCall"));
1124 code.addLine(prefixTabs
1126 + AssignToPtr(SpecNaming.AnnoInterfaceInfoInst, "value",
1130 // Return if necessary
1131 if (!construct.getFunctionHeader().isReturnVoid())
1132 code.addLine(prefixTabs + "\treturn " + SpecNaming.RET + ";");
1133 code.addLine(prefixTabs + "}");
1140 * Write a list of lines (as the whole of the file) to a file ---
1141 * newFileName. If that file does not exist, we create that file and then
1145 * @param newFileName
1146 * The name of the file to be written
1148 * The list of lines that as a whole become the content of the
1151 public static void write2File(String newFileName, ArrayList<String> content) {
1152 File newFile = new File(newFileName);
1153 newFile.getParentFile().mkdirs();
1154 if (!newFile.exists()) {
1156 newFile.createNewFile();
1157 } catch (IOException e) {
1158 e.printStackTrace();
1161 BufferedWriter bw = null;
1163 bw = new BufferedWriter(new FileWriter(newFile));
1164 for (int i = 0; i < content.size(); i++) {
1165 bw.write(content.get(i) + "\n");
1168 } catch (IOException e) {
1169 e.printStackTrace();
1174 } catch (IOException e) {
1175 e.printStackTrace();