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 String structName = construct.getStructName();
201 code.addLine(ShortComment("Declare custom value struct for "
203 code.addLine("typedef struct " + structName + " {");
204 FunctionHeader funcHeader = construct.getFunctionHeader();
206 if (!funcHeader.returnType.equals("void"))
207 code.addLine(TabbedLine(Declare(funcHeader.returnType,
210 for (VariableDeclaration decl : funcHeader.args) {
211 code.addLine(TabbedLine(Declare(decl)));
213 code.addLine("} " + structName + ";");
218 // Declare INIT annotation instrumentation function
219 code.addLine(ShortComment("Declare INIT annotation instrumentation function"));
220 code.addLine("void _createInitAnnotation();");
223 // Decalre extern "C" --- begin
224 code.addLine("#ifdef __cplusplus");
226 code.addLine("#endif");
230 code.addLine("#endif");
237 * This function generates the code for the CPP file that our specification
238 * generates automatically --- cdsspec-generated.cc.
242 * The SpecExtractor that contains the extracted information
243 * @return The generated code
245 public static Code GenerateCDSSpecCPPFile(SpecExtractor extractor) {
246 GlobalConstruct globalConstruct = extractor.getGlobalConstruct();
247 HashMap<File, ArrayList<InterfaceConstruct>> interfaceListMap = extractor.interfaceListMap;
248 HashSet<String> OPLabelSet = extractor.OPLabelSet;
250 Code code = new Code();
252 Code fieldsInit = null;
254 // Add auto-generated comments
256 code.addLine(TabbedLine("This is an implementation file auto-generated by CDSSpec compiler to"));
257 code.addLine(TabbedLine("instrument your benchmark for CDSSpec checker to check. Currently we require"));
258 code.addLine(TabbedLine("a C++ compiler that supports C++11."));
262 code.addLine("#include " + SpecNaming.CDSSpecGeneratedHeader);
263 code.addLine("#include " + SpecNaming.CDSANNOTATE);
264 code.addLine("#include " + SpecNaming.SPEC_COMMON);
265 code.addLine("#include " + SpecNaming.METHODCALL);
266 code.addLine("#include " + SpecNaming.CDSSPEC);
267 code.addLine("#include " + SpecNaming.SPECANNOTATION);
271 // Declare customized StateStruct
272 code.addLine(ShortComment("Declare customized StateStruct"));
273 code.addLine("typedef struct " + SpecNaming.StateStruct + " {");
274 for (VariableDeclaration decl : globalConstruct.declState) {
275 code.addLine(TabbedLine(Declare(decl)));
278 // Define state destructor
279 code.addLine(TabbedLine(ShortComment("Define state destructor")));
280 code.addLine(TabbedLine("~" + SpecNaming.StateStruct + "() {"));
281 if (!globalConstruct.autoGenClear) {
282 code.addLine(TabbedLine(
283 ShortComment("Execute user-defined state clear code"), 2));
285 code.addLine(TabbedLine(
286 ShortComment("Execute auto-generated state clear code"), 2));
288 globalConstruct.clearState.align(2);
289 code.addLines(globalConstruct.clearState);
290 code.addLine(TabbedLine("}"));
293 code.addLine(TabbedLine("SNAPSHOTALLOC"));
295 code.addLine("} " + SpecNaming.StateStruct + ";");
299 code.addLine(ShortComment("Definition of some c-strings (CSTR)"));
300 code.addLine(ShortComment("A special empty string"));
301 code.addLine(DeclareDefine(SpecNaming.CString, SpecNaming.EmptyCString,
305 // Interface name strings
306 code.addLine(ShortComment("Interface name strings"));
307 for (File file : interfaceListMap.keySet()) {
308 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
309 for (InterfaceConstruct construct : list) {
310 String name = construct.getName();
311 code.addLine(DeclareDefine(SpecNaming.CString,
312 SpecNaming.AppendStr(name), Quote(name)));
317 // Commutativity rule strings
318 code.addLine(ShortComment("Commutativity rule strings"));
319 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
320 CommutativityRule rule = globalConstruct.commutativityRules
322 code.addLine(DeclareDefine(SpecNaming.CString,
323 SpecNaming.AppendStr(SpecNaming.Commutativity + i),
324 Quote(rule.toString())));
328 // Ordering points label strings
329 code.addLine(ShortComment("Ordering points label strings"));
330 for (String label : OPLabelSet) {
331 code.addLine(DeclareDefine(SpecNaming.CString,
332 SpecNaming.AppendStr(label), Quote(label)));
336 // Special function name strings
337 code.addLine(ShortComment("Special function name strings"));
338 code.addLine(DeclareDefine(SpecNaming.CString,
339 SpecNaming.AppendStr(SpecNaming.InitalState), Quote("_"
340 + SpecNaming.InitalState.toLowerCase())));
341 code.addLine(DeclareDefine(SpecNaming.CString,
342 SpecNaming.AppendStr(SpecNaming.CopyState), Quote("_"
343 + SpecNaming.CopyState.toLowerCase())));
344 code.addLine(DeclareDefine(SpecNaming.CString,
345 SpecNaming.AppendStr(SpecNaming.ClearState), Quote("_"
346 + SpecNaming.ClearState.toLowerCase())));
347 code.addLine(DeclareDefine(SpecNaming.CString,
348 SpecNaming.AppendStr(SpecNaming.FinalState), Quote("_"
349 + SpecNaming.FinalState.toLowerCase())));
350 code.addLine(DeclareDefine(SpecNaming.CString,
351 SpecNaming.AppendStr(SpecNaming.PrintState), Quote("_"
352 + SpecNaming.PrintState.toLowerCase())));
355 // Interface name strings
356 for (File file : interfaceListMap.keySet()) {
357 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
358 for (InterfaceConstruct construct : list) {
359 String name = construct.getName();
360 code.addLine(ShortComment(name + " function strings"));
362 String tmpFunc = name + "_" + SpecNaming.Transition;
363 code.addLine(DeclareDefine(SpecNaming.CString,
364 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
366 tmpFunc = name + "_" + SpecNaming.PreCondition;
367 if (!construct.preCondition.isEmpty())
368 code.addLine(DeclareDefine(SpecNaming.CString,
369 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
371 code.addLine(DeclareDefine(SpecNaming.CString,
372 SpecNaming.AppendStr(tmpFunc),
373 SpecNaming.EmptyCString));
375 tmpFunc = name + "_" + SpecNaming.PostCondition;
376 if (!construct.postCondition.isEmpty())
377 code.addLine(DeclareDefine(SpecNaming.CString,
378 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
380 code.addLine(DeclareDefine(SpecNaming.CString,
381 SpecNaming.AppendStr(tmpFunc),
382 SpecNaming.EmptyCString));
384 tmpFunc = name + "_" + SpecNaming.PrintValue;
385 if (!construct.print.isEmpty())
386 code.addLine(DeclareDefine(SpecNaming.CString,
387 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
389 code.addLine(DeclareDefine(SpecNaming.CString,
390 SpecNaming.AppendStr(tmpFunc),
391 SpecNaming.EmptyCString));
397 code.addLine(ShortComment("Define @" + SpecNaming.InitalState));
398 code.addLine("void _" + SpecNaming.InitalState.toLowerCase() + "("
399 + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
400 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
401 + SpecNaming.StateInst, "new " + SpecNaming.StateStruct)));
403 for (VariableDeclaration decl : globalConstruct.declState) {
404 code.addLine(TabbedLine("#define " + decl.name + " "
405 + SpecNaming.StateInst + "->" + decl.name));
407 if (!globalConstruct.autoGenInitial)
408 code.addLine(TabbedLine(ShortComment("User-defined state intialization code")));
410 // Auto-generated the initialization function
411 code.addLine(TabbedLine(ShortComment("Auto-generated state intialization code")));
412 // Align the code with one tab
413 globalConstruct.initState.align(1);
414 code.addLines(globalConstruct.initState);
416 for (VariableDeclaration decl : globalConstruct.declState) {
417 code.addLine(TabbedLine("#undef " + decl.name));
420 code.addLine(TabbedLine(AssignToPtr(SpecNaming.Method1,
421 SpecNaming.StateInst, SpecNaming.StateInst)));
426 code.addLine(ShortComment("Define @" + SpecNaming.CopyState));
427 code.addLine("void _" + SpecNaming.CopyState.toLowerCase() + "("
428 + SpecNaming.Method + " " + "dest, " + SpecNaming.Method
430 // StateStruct *OLD = (StateStruct*) src->state;
431 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
432 + SpecNaming.OldStateInst, Brace(SpecNaming.StateStruct + "*")
433 + " src->" + SpecNaming.StateInst)));
434 // StateStruct *NEW = new StateStruct;
435 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
436 + SpecNaming.NewStateInst, "new " + SpecNaming.StateStruct)));
437 if (!globalConstruct.autoGenCopy)
438 code.addLine(TabbedLine(ShortComment("User-defined state copy statements")));
440 // Auto-generated the copy function
441 code.addLine(TabbedLine(ShortComment("Auto-generated state copy statements")));
442 globalConstruct.copyState.align(1);
443 code.addLines(globalConstruct.copyState);
445 code.addLine(TabbedLine(AssignToPtr("dest", SpecNaming.StateInst,
446 SpecNaming.NewStateInst)));
451 code.addLine(ShortComment("Define @" + SpecNaming.ClearState));
452 code.addLine("void _" + SpecNaming.ClearState.toLowerCase() + "("
453 + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
454 // Retrieve the state
455 code.addLine(TabbedLine(ShortComment("Retrieve the state")));
456 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
457 + SpecNaming.StateInst, "(" + SpecNaming.StateStruct + "*) "
458 + SpecNaming.Method1 + "->state")));
459 // Explicitly call the state destructor
460 code.addLine(TabbedLine(ShortComment("Explicitly call the state destructor")));
461 code.addLine(TabbedLine("delete " + SpecNaming.StateInst + ";"));
466 code.addLine(ShortComment("Define @" + SpecNaming.PrintState));
467 code.addLine("void _" + SpecNaming.PrintState.toLowerCase() + "("
468 + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
470 // Initialize state struct fields
471 fieldsInit = GenerateStateFieldsInitialization(SpecNaming.Method1,
472 SpecNaming.StateInst, globalConstruct);
474 code.addLines(fieldsInit);
476 if (!globalConstruct.autoGenPrint)
477 code.addLine(TabbedLine(ShortComment("Execute user-defined state printing code")));
479 // Auto-generated the copy function
480 code.addLine(TabbedLine(ShortComment("Execute auto-generated state printing code")));
482 // Align the code with one tab
483 globalConstruct.printState.align(1);
484 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 String structName1 = InterfaceConstruct
503 .createStructName(rule.method1);
504 String structName2 = InterfaceConstruct
505 .createStructName(rule.method2);
506 code.addLine(TabbedLine(
507 DeclareDefine(structName1, "*M1", "(" + structName1
508 + "*) m1->value"), 2));
509 code.addLine(TabbedLine(
510 DeclareDefine(structName2, "*M2", "(" + structName2
511 + "*) m2->value"), 2));
512 code.addLine(TabbedLine("return " + rule.condition + ";", 2));
513 code.addLine(TabbedLine("}"));
514 code.addLine(TabbedLine("return false;"));
520 // Define customized interface functions
521 for (File file : interfaceListMap.keySet()) {
522 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
523 for (InterfaceConstruct construct : list) {
526 // Define interface functions
527 String name = construct.getName();
528 String structName = construct.getStructName();
529 code.addLine("/********** " + name
530 + " functions **********/");
531 // Define @Transition for INTERFACE
532 code.addLine(ShortComment("Define @" + SpecNaming.Transition
534 code.addLine("bool _" + name + "_" + SpecNaming.Transition
535 + "(" + SpecNaming.Method + " " + SpecNaming.Method1
536 + ", " + SpecNaming.Method + " " + SpecNaming.Method2
539 // Initialize value struct fields
540 fieldsInit = GenerateInterfaceFieldsInitialization(
541 SpecNaming.Method2, SpecNaming.InterfaceValueInst,
544 code.addLines(fieldsInit);
546 construct.transition.align(1);
547 code.addLine(TabbedLine(ShortComment("Execute Transition")));
548 code.addLines(construct.transition);
550 // By default, we will return true for state transition
551 code.addLine(TabbedLine(ShortComment("By default @Transition returns true")));
552 code.addLine(TabbedLine("return true;"));
556 // Define @PreCondition
557 if (!construct.preCondition.isEmpty()) {
558 code.addLine(ShortComment("Define @"
559 + SpecNaming.PreCondition + " for " + name));
560 code.addLine("bool _" + name + "_"
561 + SpecNaming.PreCondition + "(" + SpecNaming.Method
562 + " " + SpecNaming.Method1 + ") {");
564 // Initialize value struct fields
565 fieldsInit = GenerateInterfaceFieldsInitialization(
566 SpecNaming.Method1, SpecNaming.InterfaceValueInst,
569 code.addLines(fieldsInit);
571 construct.preCondition.align(1);
572 code.addLine(TabbedLine(ShortComment("Execute PreCondition")));
573 code.addLines(construct.preCondition);
579 // Define @PostCondition
580 if (!construct.postCondition.isEmpty()) {
581 code.addLine(ShortComment("Define @"
582 + SpecNaming.PostCondition + " for " + name));
583 code.addLine("bool _" + name + "_"
584 + SpecNaming.PostCondition + "("
585 + SpecNaming.Method + " " + SpecNaming.Method1
588 // Initialize value struct fields
589 fieldsInit = GenerateInterfaceFieldsInitialization(
590 SpecNaming.Method1, SpecNaming.InterfaceValueInst,
593 code.addLines(fieldsInit);
595 construct.postCondition.align(1);
596 code.addLine(TabbedLine(ShortComment("Execute PostCondition")));
597 code.addLines(construct.postCondition);
603 if (!construct.print.isEmpty()) {
604 code.addLine(ShortComment("Define @"
605 + SpecNaming.PrintValue + " for " + name));
606 code.addLine("void _" + name + "_" + SpecNaming.PrintValue
607 + "(" + SpecNaming.Method + " "
608 + SpecNaming.Method1 + ") {");
609 // Initialize value struct fields
610 fieldsInit = GenerateInterfaceFieldsInitialization(
611 SpecNaming.Method1, SpecNaming.InterfaceValueInst,
614 code.addLines(fieldsInit);
616 construct.print.align(1);
617 if (!construct.autoGenPrint)
618 code.addLine(TabbedLine(ShortComment("Execute user-defined value printing code")));
620 // Auto-generated the value printing function
621 code.addLine(TabbedLine(ShortComment("Execute auto-generated value printing code")));
622 code.addLines(construct.print);
630 // Define INIT annotation instrumentation function
631 code.addLine(ShortComment("Define INIT annotation instrumentation function"));
632 code.addLine("void _createInitAnnotation() {");
634 // Init commutativity rules
635 code.addLine(TabbedLine(ShortComment("Init commutativity rules")));
636 code.addLine(TabbedLine(DeclareDefine("int",
637 SpecNaming.CommutativityRuleSizeInst,
638 Integer.toString(globalConstruct.commutativityRules.size()))));
639 String tmp = SpecNaming.NewSize
640 + Brace(SpecNaming.CommutativityRule + ", sizeof"
641 + Brace(SpecNaming.CommutativityRule) + " * "
642 + SpecNaming.CommutativityRuleSizeInst);
643 code.addLine(TabbedLine(DeclareDefine(SpecNaming.CommutativityRule, "*"
644 + SpecNaming.CommutativityRuleInst, tmp)));
645 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
646 CommutativityRule rule = globalConstruct.commutativityRules
648 code.addLine(TabbedLine(ShortComment("Initialize commutativity rule ")
650 // new( &commuteRules[0] )CommutativityRule(_ENQ_str, _DEQ_str,
651 // _Commutativity1_str, _checkCommutativity1)
653 + Brace(" &" + SpecNaming.CommutativityRuleInst + "["
654 + (i - 1) + "] ") + SpecNaming.CommutativityRule
655 + "(" + SpecNaming.AppendStr(rule.method1) + ", "
656 + SpecNaming.AppendStr(rule.method2) + ", "
657 + SpecNaming.AppendStr(SpecNaming.Commutativity + i) + ", "
658 + "_check" + SpecNaming.Commutativity + i + ");";
659 code.addLine(TabbedLine(line));
662 // Initialize AnnoInit
663 code.addLine(TabbedLine(ShortComment("Initialize AnnoInit")));
664 // AnnoInit *init = new AnnoInit(
665 code.addLine(TabbedLine(SpecNaming.AnnoInit + " *"
666 + SpecNaming.AnnoInitInst + " = new " + SpecNaming.AnnoInit
668 // new NamedFunction(_Initial_str, INITIAL, (void*) _initial),
669 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
670 + SpecNaming.AppendStr(SpecNaming.InitalState) + ", "
671 + SpecNaming.InitalState.toUpperCase() + ", " + "(void*) _"
672 + SpecNaming.InitalState.toLowerCase() + "),", 2));
673 // new NamedFunction(_Final_str, FINAL, (void*) NULL_FUNC),
674 line = "new " + SpecNaming.NamedFunction + "("
675 + SpecNaming.AppendStr(SpecNaming.FinalState) + ", "
676 + SpecNaming.FinalState.toUpperCase() + ", " + "(void*) ";
677 if (globalConstruct.finalState.isEmpty()) {
678 line = line + SpecNaming.NullFunc + "),";
680 line = line + "_" + SpecNaming.FinalState.toUpperCase();
682 code.addLine(TabbedLine(line, 2));
683 // new NamedFunction(_Copy_str, COPY, (void*) _copy),
684 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
685 + SpecNaming.AppendStr(SpecNaming.CopyState) + ", "
686 + SpecNaming.CopyState.toUpperCase() + ", " + "(void*) _"
687 + SpecNaming.CopyState.toLowerCase() + "),", 2));
688 // new NamedFunction(_Clear_str, CLEAR, (void*) _clear),
689 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
690 + SpecNaming.AppendStr(SpecNaming.ClearState) + ", "
691 + SpecNaming.ClearState.toUpperCase() + ", " + "(void*) _"
692 + SpecNaming.ClearState.toLowerCase() + "),", 2));
693 // new NamedFunction(_Print_str, PRINT_STATE, (void*) _print),
694 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
695 + SpecNaming.AppendStr(SpecNaming.PrintState) + ", "
696 + SpecNaming.PrintStateType + ", " + "(void*) _"
697 + SpecNaming.PrintState.toLowerCase() + "),", 2));
698 // commuteRules, CommuteRuleSize);
699 code.addLine(TabbedLine(SpecNaming.CommutativityRuleInst + ", "
700 + SpecNaming.CommutativityRuleSizeInst + ");", 2));
703 // Declare StateFunctions map
704 code.addLine(TabbedLine(ShortComment("Declare StateFunctions map")));
705 code.addLine(TabbedLine(Declare(SpecNaming.StateFunctions, "*"
706 + SpecNaming.StateFunctionsInst)));
709 // StateFunction for interface
710 for (File file : interfaceListMap.keySet()) {
711 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
712 for (InterfaceConstruct construct : list) {
713 String name = construct.getName();
714 code.addLine(TabbedLine(ShortComment("StateFunction for "
716 // stateFuncs = new StateFunctions(
717 code.addLine(TabbedLine(SpecNaming.StateFunctionsInst
718 + " = new " + SpecNaming.StateFunctions + "("));
719 // new NamedFunction(_ENQ_Transition_str, TRANSITION, (void*)
722 code.addLine(TabbedLine(
724 + SpecNaming.NamedFunction
726 + SpecNaming.AppendStr(name + "_"
727 + SpecNaming.Transition) + ", "
728 + SpecNaming.TransitionType + ", (void*) _"
729 + name + "_" + SpecNaming.Transition + "),", 2));
732 + SpecNaming.NamedFunction
734 + SpecNaming.AppendStr(name + "_"
735 + SpecNaming.PreCondition) + ", "
736 + SpecNaming.PreConditionType + ", (void*) ";
737 if (construct.preCondition.isEmpty()) {
738 line = line + SpecNaming.NullFunc + "),";
740 line = line + "_" + name + "_" + SpecNaming.PreCondition
743 code.addLine(TabbedLine(line, 2));
746 + SpecNaming.NamedFunction
748 + SpecNaming.AppendStr(name + "_"
749 + SpecNaming.PostCondition) + ", "
750 + SpecNaming.PostConditionType + ", (void*) ";
751 if (construct.postCondition.isEmpty()) {
752 line = line + SpecNaming.NullFunc + "),";
754 line = line + "_" + name + "_" + SpecNaming.PostCondition
757 code.addLine(TabbedLine(line, 2));
760 + SpecNaming.NamedFunction
762 + SpecNaming.AppendStr(name + "_"
763 + SpecNaming.PrintValue) + ", "
764 + SpecNaming.PrintValueType + ", (void*) ";
765 if (construct.print.isEmpty()) {
766 line = line + SpecNaming.NullFunc + ")";
768 line = line + "_" + name + "_" + SpecNaming.PrintValue
771 code.addLine(TabbedLine(line, 2));
772 code.addLine(TabbedLine(");"));
774 // init->addInterfaceFunctions(_ENQ_str, stateFuncs);
775 code.addLine(TabbedLine(SpecNaming.AnnoInitInst
777 + SpecNaming.AddInterfaceFunctions
778 + Brace(SpecNaming.AppendStr(name) + ", "
779 + SpecNaming.StateFunctionsInst) + ";"));
784 // Create and instrument with the INIT annotation
785 code.addLine(TabbedLine(ShortComment("Create and instrument with the INIT annotation")));
786 // cdsannotate(SPEC_ANALYSIS, new SpecAnnotation(INIT, init));
787 code.addLine(TabbedLine(SpecNaming.CDSAnnotateFunc
788 + Brace(SpecNaming.SPEC_ANALYSIS
790 + SpecNaming.SpecAnnotation
791 + Brace(SpecNaming.AnnoTypeInit + ", "
792 + SpecNaming.AnnoInitInst)) + ";"));
802 * This function generates a list of lines that initialize the fields of the
803 * global state struct. See below.
808 * StateStruct *state = (StateStruct*) _M->state;
810 * IntList * q = state->q;
815 * In this example, _M --> methodInst, state --> inst.
823 * The global state construct
824 * @return The generated code
826 public static Code GenerateStateFieldsInitialization(String methodInst,
827 String inst, GlobalConstruct construct) {
828 Code res = new Code();
829 res.addLine(ShortComment("Initialize " + SpecNaming.StateStruct
831 res.addLine(DeclareDefine(SpecNaming.StateStruct, "*" + inst, "("
832 + SpecNaming.StateStruct + "*) " + methodInst + "->state"));
833 for (VariableDeclaration decl : construct.declState) {
834 res.addLine(DeclareDefine(decl.type, decl.name, inst + "->"
842 * This function generates a list of lines that initialize the fields of a
843 * specific interface struct. See below.
848 * ENQ *info = (ENQ*) _M->value;
850 * IntList * q = info->q;
855 * In this example, ENQ --> structType, _M --> methodInst, info --> inst
863 * The corresponding interface construct
864 * @return The generated code
866 public static Code GenerateInterfaceFieldsInitialization(String methodInst,
867 String inst, InterfaceConstruct construct) {
868 Code res = new Code();
869 String name = construct.getName();
870 String structName = construct.getStructName();
871 res.addLine(ShortComment("Initialize fields for " + name));
872 // The very first assignment "
873 res.addLine(DeclareDefine(structName, "*" + inst, "(" + structName
874 + "*) " + methodInst + "->" + SpecNaming.MethodValueField));
875 // Don't leave out the RET field
876 if (!construct.getFunctionHeader().isReturnVoid()) {
877 res.addLine(DeclareDefine(construct.getFunctionHeader().returnType,
878 SpecNaming.RET, inst + "->" + SpecNaming.RET));
881 for (VariableDeclaration decl : construct.getFunctionHeader().args) {
882 res.addLine(DeclareDefine(decl.type, decl.name, inst + "->"
890 * This function generates the code to be inserted right after the ordering
891 * point construct (instrumentation code)
895 * The corresponding ordering point construct
896 * @return The generated code
898 public static Code Generate4OPConstruct(OPConstruct construct) {
899 Code code = new Code();
900 String curLine = construct.annotation;
901 String label = construct.label;
902 String prefixTabs = curLine.substring(0, curLine.indexOf("/**"));
903 if (!construct.condition.equals("true")) {
904 code.addLine(prefixTabs + "if (" + construct.condition + ")");
905 prefixTabs = prefixTabs + "\t";
908 switch (construct.type) {
910 code.addLine(prefixTabs + SpecNaming.CreateOPDefineAnnoFunc + "();");
913 code.addLine(prefixTabs + SpecNaming.CreatePotentialOPAnnoFunc
914 + "(" + SpecNaming.AppendStr(label) + ");");
917 code.addLine(prefixTabs + SpecNaming.CreateOPCheckAnnoFunc + "("
918 + SpecNaming.AppendStr(label) + ");");
921 code.addLine(prefixTabs + SpecNaming.CreateOPClearAnnoFunc + "();");
924 code.addLine(prefixTabs + SpecNaming.CreateOPClearDefineAnnoFunc
935 * This function generates the code to be inserted right after the entry
936 * construct (instrumentation code)
940 * The corresponding entry construct
943 public static Code Generate4Entry(EntryConstruct construct) {
944 Code res = new Code();
945 String curLine = construct.annotation;
946 String prefixTabs = curLine.substring(0, curLine.indexOf("/**"));
947 // _createInitAnnotation();
948 res.addLine(prefixTabs + SpecNaming.CreateInitAnnoFunc + "();");
954 * This function generates the code to be inserted right after the "@Define"
955 * construct (instrumentation code)
959 * The corresponding entry construct
962 public static Code Generate4Define(DefineConstruct construct) {
963 Code code = new Code();
965 code.addLine("/********** User-defined code in annotation (BEGIN) **********/");
966 code.addLines(construct.code);
967 code.addLine("/********** User-defined code in annotation (END) **********/");
973 * This function generates the new interface wrapper code to be inserted
974 * right after the end of the interface definition
978 * The corresponding interface construct
979 * @return The generated code
981 public static Code GenerateInterfaceWrapper(InterfaceConstruct construct) {
982 Code code = new Code();
984 String name = construct.getName();
985 String structName = construct.getStructName();
986 String beginLine = construct.getFunctionHeader().getHeaderLine();
987 Pattern regexpSpace = Pattern.compile("^(\\s*)\\S.*$");
988 Matcher matcherSpace = regexpSpace.matcher(beginLine);
989 String prefixTabs = "";
990 if (matcherSpace.find())
991 prefixTabs = matcherSpace.group(1);
993 // Add one line to separate
995 code.addLine(prefixTabs
996 + ShortComment("Generated wrapper interface for " + name));
997 if (beginLine.indexOf('{') == -1) { // We need to add the '{' to the end
999 code.addLine(beginLine + " {");
1001 code.addLine(beginLine);
1003 // Instrument with the INTERFACE_BEGIN annotations
1004 code.addLine(prefixTabs
1006 + ShortComment("Instrument with the INTERFACE_BEGIN annotation"));
1007 // CAnnoInterfaceInfo info = _createInterfaceBeginAnnotation(_DEQ_str);
1008 code.addLine(prefixTabs
1010 + DeclareDefine(SpecNaming.AnnoInterfaceInfo, "*"
1011 + SpecNaming.AnnoInterfaceInfoInst,
1012 SpecNaming.CreateInterfaceBeginAnnoFunc
1013 + Brace(SpecNaming.AppendStr(name))));
1014 // Call the actual function
1015 code.addLine(prefixTabs + "\t"
1016 + ShortComment("Call the actual function"));
1017 // bool RET = dequeue_ORIGINAL__(q, retVal, reclaimNode);
1018 code.addLine(prefixTabs + "\t"
1019 + construct.getFunctionHeader().getRenamedCall() + ";");
1022 // Initialize the value struct
1023 code.addLine(prefixTabs + "\t"
1024 + ShortComment("Initialize the value struct"));
1025 // The very first assignment "
1026 code.addLine(prefixTabs
1028 + DeclareDefine(structName,
1029 "*" + SpecNaming.InterfaceValueInst, SpecNaming.New
1030 + Brace(structName)));
1031 // Don't leave out the RET field
1032 if (!construct.getFunctionHeader().isReturnVoid())
1033 code.addLine(prefixTabs
1035 + AssignToPtr(SpecNaming.InterfaceValueInst,
1036 SpecNaming.RET, SpecNaming.RET));
1038 for (VariableDeclaration decl : construct.getFunctionHeader().args)
1039 code.addLine(prefixTabs
1041 + AssignToPtr(SpecNaming.InterfaceValueInst, decl.name,
1045 // Store the value info into the current MethodCall
1046 // _setInterfaceBeginAnnotationValue(info, value);
1047 code.addLine(prefixTabs
1049 + ShortComment("Store the value info into the current MethodCall"));
1050 code.addLine(prefixTabs
1052 + SpecNaming.SetInterfaceBeginAnnoValueFunc
1053 + Brace(SpecNaming.AnnoInterfaceInfoInst + ", "
1054 + SpecNaming.InterfaceValueInst) + ";");
1057 // Return if necessary
1058 if (!construct.getFunctionHeader().isReturnVoid())
1059 code.addLine(prefixTabs + "\treturn " + SpecNaming.RET + ";");
1060 code.addLine(prefixTabs + "}");
1067 * Write a list of lines (as the whole of the file) to a file ---
1068 * newFileName. If that file does not exist, we create that file and then
1072 * @param newFileName
1073 * The name of the file to be written
1075 * The list of lines that as a whole become the content of the
1078 public static void write2File(String newFileName, ArrayList<String> content) {
1079 File newFile = new File(newFileName);
1080 newFile.getParentFile().mkdirs();
1081 if (!newFile.exists()) {
1083 newFile.createNewFile();
1084 } catch (IOException e) {
1085 e.printStackTrace();
1088 BufferedWriter bw = null;
1090 bw = new BufferedWriter(new FileWriter(newFile));
1091 for (int i = 0; i < content.size(); i++) {
1092 bw.write(content.get(i) + "\n");
1095 } catch (IOException e) {
1096 e.printStackTrace();
1101 } catch (IOException e) {
1102 e.printStackTrace();