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 // FIXME: We don't add user-defined headers, but as a workaround we only add forward class.
159 code.addLine(ShortComment("User included headers go here"));
160 for (String header : headerFiles) {
161 code.addLine(IncludeHeader(header));
165 // code.addLine(ShortComment("Forward declaration goes here"));
166 // for (String type : extractor.forwardClass) {
167 // code.addLine("class " + type + ";");
171 code.addLine("using namespace std;");
175 code.addLine(ShortComment("Declaration of some c-strings (CSTR)"));
176 code.addLine(ShortComment("A special empty string"));
177 code.addLine(Declare("extern " + SpecNaming.CString,
178 SpecNaming.EmptyCString));
181 // Interface name strings
182 code.addLine(ShortComment("Interface name strings"));
183 for (File file : interfaceListMap.keySet()) {
184 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
185 for (InterfaceConstruct construct : list) {
186 String name = construct.getName();
187 code.addLine(Declare("extern " + SpecNaming.CString,
188 SpecNaming.AppendStr(name)));
193 // Commutativity rule strings
194 code.addLine(ShortComment("Commutativity rule strings"));
195 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
196 code.addLine(Declare("extern " + SpecNaming.CString,
197 SpecNaming.AppendStr(SpecNaming.Commutativity + i)));
201 // Ordering points label strings
202 code.addLine(ShortComment("Ordering points label strings"));
203 for (String label : OPLabelSet) {
204 code.addLine(Declare("extern " + SpecNaming.CString,
205 SpecNaming.AppendStr(label)));
209 // Special function name strings
210 code.addLine(ShortComment("Special function name strings"));
211 code.addLine(Declare("extern " + SpecNaming.CString,
212 SpecNaming.AppendStr(SpecNaming.InitalState)));
213 code.addLine(Declare("extern " + SpecNaming.CString,
214 SpecNaming.AppendStr(SpecNaming.CopyState)));
215 code.addLine(Declare("extern " + SpecNaming.CString,
216 SpecNaming.AppendStr(SpecNaming.FinalState)));
217 code.addLine(Declare("extern " + SpecNaming.CString,
218 SpecNaming.AppendStr(SpecNaming.PrintState)));
221 // Interface name strings
222 for (File file : interfaceListMap.keySet()) {
223 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
224 for (InterfaceConstruct construct : list) {
225 String name = construct.getName();
226 code.addLine(ShortComment(name + " function strings"));
228 String tmpFunc = name + "_" + SpecNaming.Transition;
229 code.addLine(Declare("extern " + SpecNaming.CString,
230 SpecNaming.AppendStr(tmpFunc)));
232 tmpFunc = name + "_" + SpecNaming.PreCondition;
233 code.addLine(Declare("extern " + SpecNaming.CString,
234 SpecNaming.AppendStr(tmpFunc)));
236 tmpFunc = name + "_" + SpecNaming.SideEffect;
237 code.addLine(Declare("extern " + SpecNaming.CString,
238 SpecNaming.AppendStr(tmpFunc)));
240 tmpFunc = name + "_" + SpecNaming.PostCondition;
241 code.addLine(Declare("extern " + SpecNaming.CString,
242 SpecNaming.AppendStr(tmpFunc)));
244 tmpFunc = name + "_" + SpecNaming.PrintValue;
245 code.addLine(Declare("extern " + SpecNaming.CString,
246 SpecNaming.AppendStr(tmpFunc)));
251 // Declare customized StateStruct
252 code.addLine(ShortComment("Declare customized StateStruct"));
253 code.addLine("typedef struct " + SpecNaming.StateStruct + " {");
254 for (VariableDeclaration decl : globalConstruct.declState) {
255 code.addLine(TabbedLine(Declare(decl)));
258 code.addLine(TabbedLine("SNAPSHOTALLOC"));
259 code.addLine("} " + SpecNaming.StateStruct + ";");
262 // Declare customized value struct
263 for (File file : interfaceListMap.keySet()) {
264 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
265 for (InterfaceConstruct construct : list) {
266 // Declare custom value struct for the interface
267 String name = construct.getName();
268 code.addLine(ShortComment("Declare custom value struct for "
270 code.addLine("typedef struct " + name + " {");
271 FunctionHeader funcHeader = construct.getFunctionHeader();
273 if (!funcHeader.returnType.equals("void"))
274 code.addLine(TabbedLine(Declare(funcHeader.returnType,
277 for (VariableDeclaration decl : funcHeader.args) {
278 code.addLine(TabbedLine(Declare(decl)));
280 code.addLine("} " + name + ";");
286 code.addLine(ShortComment("Declare @" + SpecNaming.InitalState));
287 code.addLine("void _" + SpecNaming.InitalState.toLowerCase() + "("
288 + SpecNaming.Method + " " + SpecNaming.Method1 + ");");
291 code.addLine(ShortComment("Declare @" + SpecNaming.CopyState));
292 code.addLine("void _" + SpecNaming.CopyState.toLowerCase() + "("
293 + SpecNaming.Method + " " + "dest, " + SpecNaming.Method
297 code.addLine(ShortComment("Declare @" + SpecNaming.PrintState));
298 if (!globalConstruct.printState.isEmpty()) {
299 code.addLine("void _" + SpecNaming.PrintState.toLowerCase() + "("
300 + SpecNaming.Method + " " + SpecNaming.Method1 + ");");
304 // Declare @Commutativity
305 code.addLine(ShortComment("Declare commutativity checking functions"));
306 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
307 code.addLine("bool _check" + SpecNaming.Commutativity + i + "("
308 + SpecNaming.Method + " m1, " + SpecNaming.Method + " m2);");
312 // Declare customized interface functions
313 for (File file : interfaceListMap.keySet()) {
314 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
315 for (InterfaceConstruct construct : list) {
316 // Declare interface functions
317 String name = construct.getName();
318 code.addLine("/********** " + name
319 + " functions **********/");
320 // Declare @Transition for INTERFACE
321 code.addLine(ShortComment("Declare @" + SpecNaming.Transition
323 code.addLine("void _" + name + "_" + SpecNaming.Transition
324 + "(" + SpecNaming.Method + " " + SpecNaming.Method1
325 + ", " + SpecNaming.Method + " " + SpecNaming.Method2
328 // Declare @PreCondition
329 if (!construct.preCondition.isEmpty()) {
330 code.addLine(ShortComment("Declare @"
331 + SpecNaming.PreCondition + " for " + name));
332 code.addLine("bool _" + name + "_"
333 + SpecNaming.PreCondition + "(" + SpecNaming.Method
334 + " " + SpecNaming.Method1 + ");");
337 // Declare @SideEffect
338 if (!construct.sideEffect.isEmpty()) {
339 code.addLine(ShortComment("Declare @"
340 + SpecNaming.SideEffect + " for " + name));
341 code.addLine("void _" + name + "_" + SpecNaming.SideEffect
342 + "(" + SpecNaming.Method + " "
343 + SpecNaming.Method1 + ");");
346 // Declare @PostCondition
347 if (!construct.postCondition.isEmpty()) {
348 code.addLine(ShortComment("Declare @"
349 + SpecNaming.PostCondition + " for " + name));
350 code.addLine("bool _" + name + "_"
351 + SpecNaming.PostCondition + "("
352 + SpecNaming.Method + " " + SpecNaming.Method1
357 if (!construct.print.isEmpty()) {
358 code.addLine(ShortComment("Declare @"
359 + SpecNaming.PrintValue + " for " + name));
360 code.addLine("void _" + name + "_" + SpecNaming.PrintValue
361 + "(" + SpecNaming.Method + " "
362 + SpecNaming.Method1 + ");");
368 // Declare INIT annotation instrumentation function
369 code.addLine(ShortComment("Declare INIT annotation instrumentation function"));
370 code.addLine("void _createInitAnnotation();");
372 code.addLine("#endif");
379 * This function generates the code for the CPP file that our specification
380 * generates automatically --- cdsspec-generated.cc.
384 * The SpecExtractor that contains the extracted information
385 * @return The generated code
387 public static Code GenerateCDSSpecCPPFile(SpecExtractor extractor) {
388 GlobalConstruct globalConstruct = extractor.getGlobalConstruct();
389 HashMap<File, ArrayList<InterfaceConstruct>> interfaceListMap = extractor.interfaceListMap;
390 HashSet<String> OPLabelSet = extractor.OPLabelSet;
392 Code code = new Code();
395 // Add auto-generated comments
397 code.addLine(TabbedLine("This is an implementation file auto-generated by CDSSpec compiler to"));
398 code.addLine(TabbedLine("instrument your benchmark for CDSSpec checker to check. Currently we require"));
399 code.addLine(TabbedLine("a C++ compiler that supports C++11."));
403 code.addLine("#include " + SpecNaming.CDSSpecGeneratedHeader);
407 code.addLine(ShortComment("Definition of some c-strings (CSTR)"));
408 code.addLine(ShortComment("A special empty string"));
409 code.addLine(DeclareDefine(SpecNaming.CString, SpecNaming.EmptyCString,
413 // Interface name strings
414 code.addLine(ShortComment("Interface name strings"));
415 for (File file : interfaceListMap.keySet()) {
416 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
417 for (InterfaceConstruct construct : list) {
418 String name = construct.getName();
419 code.addLine(DeclareDefine(SpecNaming.CString,
420 SpecNaming.AppendStr(name), Quote(name)));
425 // Commutativity rule strings
426 code.addLine(ShortComment("Commutativity rule strings"));
427 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
428 CommutativityRule rule = globalConstruct.commutativityRules
430 code.addLine(DeclareDefine(SpecNaming.CString,
431 SpecNaming.AppendStr(SpecNaming.Commutativity + i),
432 Quote(rule.toString())));
436 // Ordering points label strings
437 code.addLine(ShortComment("Ordering points label strings"));
438 for (String label : OPLabelSet) {
439 code.addLine(DeclareDefine(SpecNaming.CString,
440 SpecNaming.AppendStr(label), Quote(label)));
444 // Special function name strings
445 code.addLine(ShortComment("Special function name strings"));
446 code.addLine(DeclareDefine(SpecNaming.CString,
447 SpecNaming.AppendStr(SpecNaming.InitalState), Quote("_"
448 + SpecNaming.InitalState.toLowerCase())));
449 code.addLine(DeclareDefine(SpecNaming.CString,
450 SpecNaming.AppendStr(SpecNaming.CopyState), Quote("_"
451 + SpecNaming.CopyState.toLowerCase())));
452 code.addLine(DeclareDefine(SpecNaming.CString,
453 SpecNaming.AppendStr(SpecNaming.FinalState), Quote("_"
454 + SpecNaming.FinalState.toLowerCase())));
455 code.addLine(DeclareDefine(SpecNaming.CString,
456 SpecNaming.AppendStr(SpecNaming.PrintState), Quote("_"
457 + SpecNaming.PrintState.toLowerCase())));
460 // Interface name strings
461 for (File file : interfaceListMap.keySet()) {
462 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
463 for (InterfaceConstruct construct : list) {
464 String name = construct.getName();
465 code.addLine(ShortComment(name + " function strings"));
467 String tmpFunc = name + "_" + SpecNaming.Transition;
468 code.addLine(DeclareDefine(SpecNaming.CString,
469 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
471 tmpFunc = name + "_" + SpecNaming.PreCondition;
472 if (!construct.preCondition.isEmpty())
473 code.addLine(DeclareDefine(SpecNaming.CString,
474 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
476 code.addLine(DeclareDefine(SpecNaming.CString,
477 SpecNaming.AppendStr(tmpFunc),
478 SpecNaming.EmptyCString));
480 tmpFunc = name + "_" + SpecNaming.SideEffect;
481 if (!construct.sideEffect.isEmpty())
482 code.addLine(DeclareDefine(SpecNaming.CString,
483 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
485 code.addLine(DeclareDefine(SpecNaming.CString,
486 SpecNaming.AppendStr(tmpFunc),
487 SpecNaming.EmptyCString));
489 tmpFunc = name + "_" + SpecNaming.PostCondition;
490 if (!construct.postCondition.isEmpty())
491 code.addLine(DeclareDefine(SpecNaming.CString,
492 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
494 code.addLine(DeclareDefine(SpecNaming.CString,
495 SpecNaming.AppendStr(tmpFunc),
496 SpecNaming.EmptyCString));
498 tmpFunc = name + "_" + SpecNaming.PrintValue;
499 if (!construct.print.isEmpty())
500 code.addLine(DeclareDefine(SpecNaming.CString,
501 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
503 code.addLine(DeclareDefine(SpecNaming.CString,
504 SpecNaming.AppendStr(tmpFunc),
505 SpecNaming.EmptyCString));
511 code.addLine(ShortComment("Define @" + SpecNaming.InitalState));
512 code.addLine("void _" + SpecNaming.InitalState.toLowerCase() + "("
513 + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
514 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
515 + SpecNaming.StateInst, "new " + SpecNaming.StateStruct)));
517 for (VariableDeclaration decl : globalConstruct.declState) {
518 code.addLine(TabbedLine("#define " + decl.name + " "
519 + SpecNaming.StateInst + "->" + decl.name));
521 code.addLine(TabbedLine(ShortComment("User-defined intial state code")));
522 // Align the code with one tab
523 globalConstruct.initState.align(1);
524 code.addLines(globalConstruct.initState);
526 for (VariableDeclaration decl : globalConstruct.declState) {
527 code.addLine(TabbedLine("#undef " + decl.name));
530 code.addLine(TabbedLine(AssignToPtr(SpecNaming.Method1,
531 SpecNaming.StateInst, SpecNaming.StateInst)));
536 code.addLine(ShortComment("Define @" + SpecNaming.CopyState));
537 code.addLine("void _" + SpecNaming.CopyState.toLowerCase() + "("
538 + SpecNaming.Method + " " + "dest, " + SpecNaming.Method
540 // StateStruct *OLD = (StateStruct*) src->state;
541 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
542 + SpecNaming.OldStateInst, Brace(SpecNaming.StateStruct + "*")
543 + " src->" + SpecNaming.StateInst)));
544 // StateStruct *NEW = new StateStruct;
545 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
546 + SpecNaming.NewStateInst, "new " + SpecNaming.StateStruct)));
547 if (!globalConstruct.autoGenCopy)
548 code.addLine(TabbedLine(ShortComment("User-defined state copy statements")));
550 // Auto-generated the copy function
551 code.addLine(TabbedLine(ShortComment("Auto-generated state copy statements")));
552 globalConstruct.copyState.align(1);
553 code.addLines(globalConstruct.copyState);
555 code.addLine(TabbedLine(AssignToPtr("dest", SpecNaming.StateInst,
556 SpecNaming.NewStateInst)));
561 if (!globalConstruct.printState.isEmpty()) {
562 code.addLine(ShortComment("Define @" + SpecNaming.PrintState));
563 code.addLine("void _" + SpecNaming.PrintState.toLowerCase() + "("
564 + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
566 // Initialize state struct fields
567 Code fieldsInit = GenerateStateFieldsInitialization(
568 SpecNaming.Method1, SpecNaming.StateInst, globalConstruct);
570 code.addLines(fieldsInit);
572 code.addLine(TabbedLine(ShortComment("Execute the print-out")));
573 // Align the code with one tab
574 globalConstruct.printState.align(1);
575 code.addLines(globalConstruct.printState);
580 // Define @Commutativity
581 code.addLine(ShortComment("Define commutativity checking functions"));
582 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
583 CommutativityRule rule = globalConstruct.commutativityRules
585 code.addLine("bool _check" + SpecNaming.Commutativity + i + "("
586 + SpecNaming.Method + " m1, " + SpecNaming.Method
588 // if (m1->name == _ENQ_str && m2->name == _DEQ_str) {
589 code.addLine(TabbedLine("if (m1->name == "
590 + SpecNaming.AppendStr(rule.method1) + " && m2->name == "
591 + SpecNaming.AppendStr(rule.method2) + ") {"));
592 // Initialize M1 & M2 in commutativity rule
593 // e.g. ENQ *M1 = (ENQ*) m1->value;
594 code.addLine(TabbedLine(
595 DeclareDefine(rule.method1, "*M1", "(" + rule.method1
596 + "*) m1->value"), 2));
597 code.addLine(TabbedLine(
598 DeclareDefine(rule.method2, "*M2", "(" + rule.method2
599 + "*) m2->value"), 2));
600 code.addLine(TabbedLine("return " + rule.condition + ";", 2));
601 code.addLine(TabbedLine("}"));
602 code.addLine(TabbedLine("return false;"));
608 // Define customized interface functions
609 for (File file : interfaceListMap.keySet()) {
610 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
611 for (InterfaceConstruct construct : list) {
612 Code fieldsInit = null;
614 // Define interface functions
615 String name = construct.getName();
616 code.addLine("/********** " + name
617 + " functions **********/");
618 // Define @Transition for INTERFACE
619 code.addLine(ShortComment("Define @" + SpecNaming.Transition
621 code.addLine("void _" + name + "_" + SpecNaming.Transition
622 + "(" + SpecNaming.Method + " " + SpecNaming.Method1
623 + ", " + SpecNaming.Method + " " + SpecNaming.Method2
626 // Initialize value struct fields
627 fieldsInit = GenerateInterfaceFieldsInitialization(
628 SpecNaming.Method2, "value", construct);
630 code.addLines(fieldsInit);
632 construct.transition.align(1);
633 code.addLine(TabbedLine(ShortComment("Execute Transition")));
634 code.addLines(construct.transition);
639 // Define @PreCondition
640 if (!construct.preCondition.isEmpty()) {
641 code.addLine(ShortComment("Define @"
642 + SpecNaming.PreCondition + " for " + name));
643 code.addLine("bool _" + name + "_"
644 + SpecNaming.PreCondition + "(" + SpecNaming.Method
645 + " " + SpecNaming.Method1 + ") {");
647 // Initialize value struct fields
648 fieldsInit = GenerateInterfaceFieldsInitialization(
649 SpecNaming.Method1, "value", construct);
651 code.addLines(fieldsInit);
653 construct.preCondition.align(1);
654 code.addLine(TabbedLine(ShortComment("Execute PreCondition")));
655 code.addLines(construct.preCondition);
661 // Define @SideEffect
662 if (!construct.sideEffect.isEmpty()) {
663 code.addLine(ShortComment("Define @"
664 + SpecNaming.SideEffect + " for " + name));
665 code.addLine("void _" + name + "_" + SpecNaming.SideEffect
666 + "(" + SpecNaming.Method + " "
667 + SpecNaming.Method1 + ") {");
669 // Initialize value struct fields
670 fieldsInit = GenerateInterfaceFieldsInitialization(
671 SpecNaming.Method1, "value", construct);
673 code.addLines(fieldsInit);
675 construct.sideEffect.align(1);
676 code.addLine(TabbedLine(ShortComment("Execute SideEffect")));
677 code.addLines(construct.sideEffect);
682 // Define @PostCondition
683 if (!construct.postCondition.isEmpty()) {
684 code.addLine(ShortComment("Define @"
685 + SpecNaming.PostCondition + " for " + name));
686 code.addLine("bool _" + name + "_"
687 + SpecNaming.PostCondition + "("
688 + SpecNaming.Method + " " + SpecNaming.Method1
691 // Initialize value struct fields
692 fieldsInit = GenerateInterfaceFieldsInitialization(
693 SpecNaming.Method1, "value", construct);
695 code.addLines(fieldsInit);
697 construct.postCondition.align(1);
698 code.addLine(TabbedLine(ShortComment("Execute PostCondition")));
699 code.addLines(construct.postCondition);
705 if (!construct.print.isEmpty()) {
706 code.addLine(ShortComment("Define @"
707 + SpecNaming.PrintValue + " for " + name));
708 code.addLine("void _" + name + "_" + SpecNaming.PrintValue
709 + "(" + SpecNaming.Method + " "
710 + SpecNaming.Method1 + ") {");
711 // Initialize value struct fields
712 fieldsInit = GenerateInterfaceFieldsInitialization(
713 SpecNaming.Method1, "value", construct);
715 code.addLines(fieldsInit);
717 construct.print.align(1);
718 code.addLine(TabbedLine(ShortComment("Execute Print")));
719 code.addLines(construct.print);
727 // Define INIT annotation instrumentation function
728 code.addLine(ShortComment("Define INIT annotation instrumentation function"));
729 code.addLine("void _createInitAnnotation() {");
731 // Init commutativity rules
732 code.addLine(TabbedLine(ShortComment("Init commutativity rules")));
733 code.addLine(TabbedLine(DeclareDefine("int",
734 SpecNaming.CommutativityRuleSizeInst,
735 Integer.toString(globalConstruct.commutativityRules.size()))));
736 String tmp = SpecNaming.NewSize
737 + Brace(SpecNaming.CommutativityRule + ", sizeof"
738 + Brace(SpecNaming.CommutativityRule) + " * "
739 + SpecNaming.CommutativityRuleSizeInst);
740 code.addLine(TabbedLine(DeclareDefine(SpecNaming.CommutativityRule, "*"
741 + SpecNaming.CommutativityRuleInst, tmp)));
742 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
743 CommutativityRule rule = globalConstruct.commutativityRules
745 code.addLine(TabbedLine(ShortComment("Initialize commutativity rule ")
747 // new( &commuteRules[0] )CommutativityRule(_ENQ_str, _DEQ_str,
748 // _Commutativity1_str, _checkCommutativity1)
750 + Brace(" &" + SpecNaming.CommutativityRuleInst + "["
751 + (i - 1) + "] ") + SpecNaming.CommutativityRule
752 + "(" + SpecNaming.AppendStr(rule.method1) + ", "
753 + SpecNaming.AppendStr(rule.method2) + ", "
754 + SpecNaming.AppendStr(SpecNaming.Commutativity + i) + ", "
755 + "_check" + SpecNaming.Commutativity + i + ");";
756 code.addLine(TabbedLine(line));
759 // Initialize AnnoInit
760 code.addLine(TabbedLine(ShortComment("Initialize AnnoInit")));
761 // AnnoInit *init = new AnnoInit(
762 code.addLine(TabbedLine(SpecNaming.AnnoInit + " *"
763 + SpecNaming.AnnoInitInst + " = new " + SpecNaming.AnnoInit
765 // new NamedFunction(_Initial_str, INITIAL, (void*) _initial),
766 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
767 + SpecNaming.AppendStr(SpecNaming.InitalState) + ", "
768 + SpecNaming.InitalState.toUpperCase() + ", " + "(void*) _"
769 + SpecNaming.InitalState.toLowerCase() + "),", 2));
770 // new NamedFunction(_Final_str, FINAL, (void*) NULL_FUNC),
771 line = "new " + SpecNaming.NamedFunction + "("
772 + SpecNaming.AppendStr(SpecNaming.FinalState) + ", "
773 + SpecNaming.FinalState.toUpperCase() + ", " + "(void*) ";
774 if (globalConstruct.finalState.isEmpty()) {
775 line = line + SpecNaming.NullFunc + "),";
777 line = line + "_" + SpecNaming.FinalState.toUpperCase();
779 code.addLine(TabbedLine(line, 2));
780 // new NamedFunction(_Copy_str, COPY, (void*) _copy),
781 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
782 + SpecNaming.AppendStr(SpecNaming.CopyState) + ", "
783 + SpecNaming.CopyState.toUpperCase() + ", " + "(void*) _"
784 + SpecNaming.CopyState.toLowerCase() + "),", 2));
785 // new NamedFunction(_Print_str, PRINT_STATE, (void*) _print),
786 line = "new " + SpecNaming.NamedFunction + "("
787 + SpecNaming.AppendStr(SpecNaming.PrintState) + ", "
788 + SpecNaming.PrintStateType + ", " + "(void*)";
789 if (globalConstruct.printState.isEmpty()) {
790 line = line + SpecNaming.NullFunc + "),";
792 line = line + "_" + SpecNaming.PrintState.toLowerCase() + "),";
794 code.addLine(TabbedLine(line, 2));
795 // commuteRules, CommuteRuleSize);
796 code.addLine(TabbedLine(SpecNaming.CommutativityRuleInst + ", "
797 + SpecNaming.CommutativityRuleSizeInst + ");", 2));
800 // Declare StateFunctions map
801 code.addLine(TabbedLine(ShortComment("Declare StateFunctions map")));
802 code.addLine(TabbedLine(Declare(SpecNaming.StateFunctions, "*"
803 + SpecNaming.StateFunctionsInst)));
806 // StateFunction for interface
807 for (File file : interfaceListMap.keySet()) {
808 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
809 for (InterfaceConstruct construct : list) {
810 String name = construct.getName();
811 code.addLine(TabbedLine(ShortComment("StateFunction for "
813 // stateFuncs = new StateFunctions(
814 code.addLine(TabbedLine(SpecNaming.StateFunctionsInst
815 + " = new " + SpecNaming.StateFunctions + "("));
816 // new NamedFunction(_ENQ_Transition_str, TRANSITION, (void*)
819 code.addLine(TabbedLine(
821 + SpecNaming.NamedFunction
823 + SpecNaming.AppendStr(name + "_"
824 + SpecNaming.Transition) + ", "
825 + SpecNaming.TransitionType + ", (void*) _"
826 + name + "_" + SpecNaming.Transition + "),", 2));
829 + SpecNaming.NamedFunction
831 + SpecNaming.AppendStr(name + "_"
832 + SpecNaming.PreCondition) + ", "
833 + SpecNaming.PreConditionType + ", (void*) ";
834 if (construct.preCondition.isEmpty()) {
835 line = line + SpecNaming.NullFunc + "),";
837 line = line + "_" + name + "_" + SpecNaming.PreCondition
840 code.addLine(TabbedLine(line, 2));
843 + SpecNaming.NamedFunction
845 + SpecNaming.AppendStr(name + "_"
846 + SpecNaming.SideEffect) + ", "
847 + SpecNaming.SideEffectType + ", (void*) ";
848 if (construct.sideEffect.isEmpty()) {
849 line = line + SpecNaming.NullFunc + "),";
851 line = line + "_" + name + "_" + SpecNaming.SideEffect
854 code.addLine(TabbedLine(line, 2));
857 + SpecNaming.NamedFunction
859 + SpecNaming.AppendStr(name + "_"
860 + SpecNaming.PostCondition) + ", "
861 + SpecNaming.PostConditionType + ", (void*) ";
862 if (construct.postCondition.isEmpty()) {
863 line = line + SpecNaming.NullFunc + "),";
865 line = line + "_" + name + "_" + SpecNaming.PostCondition
868 code.addLine(TabbedLine(line, 2));
871 + SpecNaming.NamedFunction
873 + SpecNaming.AppendStr(name + "_"
874 + SpecNaming.PrintValue) + ", "
875 + SpecNaming.PrintValueType + ", (void*) ";
876 if (construct.print.isEmpty()) {
877 line = line + SpecNaming.NullFunc + ")";
879 line = line + "_" + name + "_" + SpecNaming.PrintValue
882 code.addLine(TabbedLine(line, 2));
883 code.addLine(TabbedLine(");"));
885 // init->addInterfaceFunctions(_ENQ_str, stateFuncs);
886 code.addLine(TabbedLine(SpecNaming.AnnoInitInst
888 + SpecNaming.AddInterfaceFunctions
889 + Brace(SpecNaming.AppendStr(name) + ", "
890 + SpecNaming.StateFunctionsInst) + ";"));
895 // Create and instrument with the INIT annotation
896 code.addLine(TabbedLine(ShortComment("Create and instrument with the INIT annotation")));
897 // cdsannotate(SPEC_ANALYSIS, new SpecAnnotation(INIT, init));
898 code.addLine(TabbedLine(SpecNaming.CDSAnnotateFunc
899 + Brace(SpecNaming.SPEC_ANALYSIS
901 + SpecNaming.SpecAnnotation
902 + Brace(SpecNaming.AnnoTypeInit + ", "
903 + SpecNaming.AnnoInitInst)) + ";"));
913 * This function generates a list of lines that initialize the fields of the
914 * global state struct. See below.
919 * StateStruct *state = (StateStruct*) _M->state;
921 * IntList * q = state->q;
926 * In this example, _M --> methodInst, state --> inst.
934 * The global state construct
935 * @return The generated code
937 public static Code GenerateStateFieldsInitialization(String methodInst,
938 String inst, GlobalConstruct construct) {
939 Code res = new Code();
940 res.addLine(ShortComment("Initialize " + SpecNaming.StateStruct
942 res.addLine(DeclareDefine(SpecNaming.StateStruct, "*" + inst, "("
943 + SpecNaming.StateStruct + "*) " + methodInst + "->state"));
944 for (VariableDeclaration decl : construct.declState) {
945 res.addLine(DeclareDefine(decl.type, decl.name, inst + "->"
953 * This function generates a list of lines that initialize the fields of a
954 * specific interface struct. See below.
959 * ENQ *info = (ENQ*) _M->value;
961 * IntList * q = info->q;
966 * In this example, ENQ --> structType, _M --> methodInst, info --> inst
974 * The corresponding interface construct
975 * @return The generated code
977 public static Code GenerateInterfaceFieldsInitialization(String methodInst,
978 String inst, InterfaceConstruct construct) {
979 Code res = new Code();
980 String name = construct.getName();
981 res.addLine(ShortComment("Initialize fields for " + name));
982 // The very first assignment "
983 res.addLine(DeclareDefine(name, "*" + inst, "(" + name + "*) "
984 + methodInst + "->value"));
985 // Don't leave out the RET field
986 if (!construct.getFunctionHeader().isReturnVoid()) {
987 res.addLine(DeclareDefine(construct.getFunctionHeader().returnType,
988 SpecNaming.RET, "value->" + SpecNaming.RET));
991 for (VariableDeclaration decl : construct.getFunctionHeader().args) {
992 res.addLine(DeclareDefine(decl.type, decl.name, inst + "->"
1000 * This function generates the code to be inserted right after the ordering
1001 * point construct (instrumentation code)
1005 * The corresponding ordering point construct
1006 * @return The generated code
1008 public static Code Generate4OPConstruct(OPConstruct construct) {
1009 Code code = new Code();
1010 String curLine = construct.annotation;
1011 String label = construct.label;
1012 String prefixTabs = curLine.substring(0, curLine.indexOf("/**"));
1013 code.addLine(prefixTabs + "if (" + construct.condition + ")");
1014 switch (construct.type) {
1016 code.addLine(prefixTabs + "\t" + SpecNaming.CreateOPDefineAnnoFunc
1020 code.addLine(prefixTabs + "\t"
1021 + SpecNaming.CreatePotentialOPAnnoFunc + "("
1022 + SpecNaming.AppendStr(label) + ");");
1025 code.addLine(prefixTabs + "\t" + SpecNaming.CreateOPCheckAnnoFunc
1026 + "(" + SpecNaming.AppendStr(label) + ");");
1029 code.addLine(prefixTabs + "\t" + SpecNaming.CreateOPClearAnnoFunc
1033 code.addLine(prefixTabs + "\t"
1034 + SpecNaming.CreateOPClearDefineAnnoFunc + "();");
1044 * This function generates the code to be inserted right after the entry
1045 * construct (instrumentation code)
1049 * The corresponding entry construct
1052 public static Code Generate4Entry(EntryConstruct construct) {
1053 Code res = new Code();
1054 String curLine = construct.annotation;
1055 String prefixTabs = curLine.substring(0, curLine.indexOf("/**"));
1056 // _createInitAnnotation();
1057 res.addLine(prefixTabs + SpecNaming.CreateInitAnnoFunc + "();");
1063 * This function generates the new interface wrapper code to be inserted
1064 * right after the end of the interface definition
1068 * The corresponding interface construct
1069 * @return The generated code
1071 public static Code GenerateInterfaceWrapper(InterfaceConstruct construct) {
1072 Code code = new Code();
1074 String name = construct.getName();
1075 String beginLine = construct.getFunctionHeader().getHeaderLine();
1076 Pattern regexpSpace = Pattern.compile("^(\\s*)\\S.*$");
1077 Matcher matcherSpace = regexpSpace.matcher(beginLine);
1078 String prefixTabs = "";
1079 if (matcherSpace.find())
1080 prefixTabs = matcherSpace.group(1);
1082 // Add one line to separate
1084 code.addLine(prefixTabs
1085 + ShortComment("Generated wrapper interface for " + name));
1086 if (beginLine.indexOf('{') == -1) { // We need to add the '{' to the end
1088 code.addLine(beginLine + " {");
1090 code.addLine(beginLine);
1092 // Instrument with the INTERFACE_BEGIN annotation
1093 code.addLine(prefixTabs
1095 + ShortComment("Instrument with the INTERFACE_BEGIN annotation"));
1096 // AnnoInterfaceInfo *info = _createInterfaceBeginAnnotation(_DEQ_str);
1097 code.addLine(prefixTabs
1099 + DeclareDefine(SpecNaming.AnnoInterfaceInfo, "*"
1100 + SpecNaming.AnnoInterfaceInfoInst,
1101 SpecNaming.CreateInterfaceBeginAnnoFunc
1102 + Brace(SpecNaming.AppendStr(name))));
1103 // Call the actual function
1104 code.addLine(prefixTabs + "\t"
1105 + ShortComment("Call the actual function"));
1106 // bool RET = dequeue_ORIGINAL__(q, retVal, reclaimNode);
1107 code.addLine(prefixTabs + "\t"
1108 + construct.getFunctionHeader().getRenamedCall() + ";");
1111 // Initialize the value struct
1112 code.addLine(prefixTabs + "\t"
1113 + ShortComment("Initialize the value struct"));
1114 // The very first assignment "
1115 code.addLine(prefixTabs + "\t"
1116 + DeclareDefine(name, "*value", "new " + name));
1117 // Don't leave out the RET field
1118 if (!construct.getFunctionHeader().isReturnVoid())
1119 code.addLine(prefixTabs + "\t"
1120 + AssignToPtr("value", SpecNaming.RET, SpecNaming.RET));
1122 for (VariableDeclaration decl : construct.getFunctionHeader().args)
1123 code.addLine(prefixTabs + "\t"
1124 + AssignToPtr("value", decl.name, decl.name));
1127 // Store the value info into the current MethodCall
1128 code.addLine(prefixTabs
1130 + ShortComment("Store the value info into the current MethodCall"));
1131 code.addLine(prefixTabs
1133 + AssignToPtr(SpecNaming.AnnoInterfaceInfoInst, "value",
1137 // Return if necessary
1138 if (!construct.getFunctionHeader().isReturnVoid())
1139 code.addLine(prefixTabs + "\treturn " + SpecNaming.RET + ";");
1140 code.addLine(prefixTabs + "}");
1147 * Write a list of lines (as the whole of the file) to a file ---
1148 * newFileName. If that file does not exist, we create that file and then
1152 * @param newFileName
1153 * The name of the file to be written
1155 * The list of lines that as a whole become the content of the
1158 public static void write2File(String newFileName, ArrayList<String> content) {
1159 File newFile = new File(newFileName);
1160 newFile.getParentFile().mkdirs();
1161 if (!newFile.exists()) {
1163 newFile.createNewFile();
1164 } catch (IOException e) {
1165 e.printStackTrace();
1168 BufferedWriter bw = null;
1170 bw = new BufferedWriter(new FileWriter(newFile));
1171 for (int i = 0; i < content.size(); i++) {
1172 bw.write(content.get(i) + "\n");
1175 } catch (IOException e) {
1176 e.printStackTrace();
1181 } catch (IOException e) {
1182 e.printStackTrace();