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)"));
173 code.addLine(ShortComment("A special empty string"));
174 code.addLine(Declare("extern " + SpecNaming.CString,
175 SpecNaming.EmptyCString));
178 // Interface name strings
179 code.addLine(ShortComment("Interface name strings"));
180 for (File file : interfaceListMap.keySet()) {
181 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
182 for (InterfaceConstruct construct : list) {
183 String name = construct.getName();
184 code.addLine(Declare("extern " + SpecNaming.CString,
185 SpecNaming.AppendStr(name)));
190 // Commutativity rule strings
191 code.addLine(ShortComment("Commutativity rule strings"));
192 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
193 code.addLine(Declare("extern " + SpecNaming.CString,
194 SpecNaming.AppendStr(SpecNaming.Commutativity + i)));
198 // Ordering points label strings
199 code.addLine(ShortComment("Ordering points label strings"));
200 for (String label : OPLabelSet) {
201 code.addLine(Declare("extern " + SpecNaming.CString,
202 SpecNaming.AppendStr(label)));
206 // Special function name strings
207 code.addLine(ShortComment("Special function name strings"));
208 code.addLine(Declare("extern " + SpecNaming.CString,
209 SpecNaming.AppendStr(SpecNaming.InitalState)));
210 code.addLine(Declare("extern " + SpecNaming.CString,
211 SpecNaming.AppendStr(SpecNaming.CopyState)));
212 code.addLine(Declare("extern " + SpecNaming.CString,
213 SpecNaming.AppendStr(SpecNaming.FinalState)));
214 code.addLine(Declare("extern " + SpecNaming.CString,
215 SpecNaming.AppendStr(SpecNaming.PrintState)));
218 // Interface name strings
219 for (File file : interfaceListMap.keySet()) {
220 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
221 for (InterfaceConstruct construct : list) {
222 String name = construct.getName();
223 code.addLine(ShortComment(name + " function strings"));
225 String tmpFunc = name + "_" + SpecNaming.Transition;
226 code.addLine(Declare("extern " + SpecNaming.CString,
227 SpecNaming.AppendStr(tmpFunc)));
229 tmpFunc = name + "_" + SpecNaming.PreCondition;
230 code.addLine(Declare("extern " + SpecNaming.CString,
231 SpecNaming.AppendStr(tmpFunc)));
233 tmpFunc = name + "_" + SpecNaming.SideEffect;
234 code.addLine(Declare("extern " + SpecNaming.CString,
235 SpecNaming.AppendStr(tmpFunc)));
237 tmpFunc = name + "_" + SpecNaming.PostCondition;
238 code.addLine(Declare("extern " + SpecNaming.CString,
239 SpecNaming.AppendStr(tmpFunc)));
241 tmpFunc = name + "_" + SpecNaming.PrintValue;
242 code.addLine(Declare("extern " + SpecNaming.CString,
243 SpecNaming.AppendStr(tmpFunc)));
248 // Declare customized value struct
249 for (File file : interfaceListMap.keySet()) {
250 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
251 for (InterfaceConstruct construct : list) {
252 // Declare custom value struct for the interface
253 String name = construct.getName();
254 code.addLine(ShortComment("Declare custom value struct for "
256 code.addLine("typedef struct " + name + " {");
257 FunctionHeader funcHeader = construct.getFunctionHeader();
259 if (!funcHeader.returnType.equals("void"))
260 code.addLine(TabbedLine(Declare(funcHeader.returnType,
263 for (VariableDeclaration decl : funcHeader.args) {
264 code.addLine(TabbedLine(Declare(decl)));
266 code.addLine("} " + name + ";");
272 code.addLine(ShortComment("Declare @" + SpecNaming.InitalState));
273 code.addLine("void _" + SpecNaming.InitalState.toLowerCase() + "("
274 + SpecNaming.Method + " " + SpecNaming.Method1 + ");");
277 code.addLine(ShortComment("Declare @" + SpecNaming.CopyState));
278 code.addLine("void _" + SpecNaming.CopyState.toLowerCase() + "("
279 + SpecNaming.Method + " " + "dest, " + SpecNaming.Method
283 code.addLine(ShortComment("Declare @" + SpecNaming.PrintState));
284 if (!globalConstruct.printState.isEmpty()) {
285 code.addLine("void _" + SpecNaming.PrintState.toLowerCase() + "("
286 + SpecNaming.Method + " " + SpecNaming.Method1 + ");");
290 // Declare @Commutativity
291 code.addLine(ShortComment("Declare commutativity checking functions"));
292 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
293 code.addLine("bool _check" + SpecNaming.Commutativity + i + "("
294 + SpecNaming.Method + " m1, " + SpecNaming.Method + " m2);");
298 // Declare customized interface functions
299 for (File file : interfaceListMap.keySet()) {
300 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
301 for (InterfaceConstruct construct : list) {
302 // Declare interface functions
303 String name = construct.getName();
304 code.addLine("/********** " + name
305 + " functions **********/");
306 // Declare @Transition for INTERFACE
307 code.addLine(ShortComment("Declare @" + SpecNaming.Transition
309 code.addLine("void _" + name + "_" + SpecNaming.Transition
310 + "(" + SpecNaming.Method + " " + SpecNaming.Method1
311 + ", " + SpecNaming.Method + " " + SpecNaming.Method2
314 // Declare @PreCondition
315 if (!construct.preCondition.isEmpty()) {
316 code.addLine(ShortComment("Declare @"
317 + SpecNaming.PreCondition + " for " + name));
318 code.addLine("bool _" + name + "_"
319 + SpecNaming.PreCondition + "(" + SpecNaming.Method
320 + " " + SpecNaming.Method1 + ");");
323 // Declare @SideEffect
324 if (!construct.sideEffect.isEmpty()) {
325 code.addLine(ShortComment("Declare @"
326 + SpecNaming.SideEffect + " for " + name));
327 code.addLine("void _" + name + "_" + SpecNaming.SideEffect
328 + "(" + SpecNaming.Method + " "
329 + SpecNaming.Method1 + ");");
332 // Declare @PostCondition
333 if (!construct.postCondition.isEmpty()) {
334 code.addLine(ShortComment("Declare @"
335 + SpecNaming.PostCondition + " for " + name));
336 code.addLine("bool _" + name + "_"
337 + SpecNaming.PostCondition + "("
338 + SpecNaming.Method + " " + SpecNaming.Method1
343 if (!construct.print.isEmpty()) {
344 code.addLine(ShortComment("Declare @"
345 + SpecNaming.PrintValue + " for " + name));
346 code.addLine("void _" + name + "_" + SpecNaming.PrintValue
347 + "(" + SpecNaming.Method + " "
348 + SpecNaming.Method1 + ");");
354 // Declare INIT annotation instrumentation function
355 code.addLine(ShortComment("Declare INIT annotation instrumentation function"));
356 code.addLine("void _createInitAnnotation();");
359 // Decalre extern "C" --- begin
360 code.addLine("#ifdef __cplusplus");
362 code.addLine("#endif");
366 code.addLine("#endif");
373 * This function generates the code for the CPP file that our specification
374 * generates automatically --- cdsspec-generated.cc.
378 * The SpecExtractor that contains the extracted information
379 * @return The generated code
381 public static Code GenerateCDSSpecCPPFile(SpecExtractor extractor) {
382 GlobalConstruct globalConstruct = extractor.getGlobalConstruct();
383 HashMap<File, ArrayList<InterfaceConstruct>> interfaceListMap = extractor.interfaceListMap;
384 HashSet<String> OPLabelSet = extractor.OPLabelSet;
386 Code code = new Code();
389 // Add auto-generated comments
391 code.addLine(TabbedLine("This is an implementation file auto-generated by CDSSpec compiler to"));
392 code.addLine(TabbedLine("instrument your benchmark for CDSSpec checker to check. Currently we require"));
393 code.addLine(TabbedLine("a C++ compiler that supports C++11."));
397 code.addLine("#include " + SpecNaming.CDSSpecGeneratedHeader);
398 code.addLine("#include " + SpecNaming.CDSANNOTATE);
399 code.addLine("#include " + SpecNaming.SPEC_COMMON);
400 code.addLine("#include " + SpecNaming.METHODCALL);
401 code.addLine("#include " + SpecNaming.CDSSPEC);
402 code.addLine("#include " + SpecNaming.SPECANNOTATION);
406 // Declare customized StateStruct
407 code.addLine(ShortComment("Declare customized StateStruct"));
408 code.addLine("typedef struct " + SpecNaming.StateStruct + " {");
409 for (VariableDeclaration decl : globalConstruct.declState) {
410 code.addLine(TabbedLine(Declare(decl)));
413 code.addLine(TabbedLine("SNAPSHOTALLOC"));
414 code.addLine("} " + SpecNaming.StateStruct + ";");
418 code.addLine(ShortComment("Definition of some c-strings (CSTR)"));
419 code.addLine(ShortComment("A special empty string"));
420 code.addLine(DeclareDefine(SpecNaming.CString, SpecNaming.EmptyCString,
424 // Interface name strings
425 code.addLine(ShortComment("Interface name strings"));
426 for (File file : interfaceListMap.keySet()) {
427 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
428 for (InterfaceConstruct construct : list) {
429 String name = construct.getName();
430 code.addLine(DeclareDefine(SpecNaming.CString,
431 SpecNaming.AppendStr(name), Quote(name)));
436 // Commutativity rule strings
437 code.addLine(ShortComment("Commutativity rule strings"));
438 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
439 CommutativityRule rule = globalConstruct.commutativityRules
441 code.addLine(DeclareDefine(SpecNaming.CString,
442 SpecNaming.AppendStr(SpecNaming.Commutativity + i),
443 Quote(rule.toString())));
447 // Ordering points label strings
448 code.addLine(ShortComment("Ordering points label strings"));
449 for (String label : OPLabelSet) {
450 code.addLine(DeclareDefine(SpecNaming.CString,
451 SpecNaming.AppendStr(label), Quote(label)));
455 // Special function name strings
456 code.addLine(ShortComment("Special function name strings"));
457 code.addLine(DeclareDefine(SpecNaming.CString,
458 SpecNaming.AppendStr(SpecNaming.InitalState), Quote("_"
459 + SpecNaming.InitalState.toLowerCase())));
460 code.addLine(DeclareDefine(SpecNaming.CString,
461 SpecNaming.AppendStr(SpecNaming.CopyState), Quote("_"
462 + SpecNaming.CopyState.toLowerCase())));
463 code.addLine(DeclareDefine(SpecNaming.CString,
464 SpecNaming.AppendStr(SpecNaming.FinalState), Quote("_"
465 + SpecNaming.FinalState.toLowerCase())));
466 code.addLine(DeclareDefine(SpecNaming.CString,
467 SpecNaming.AppendStr(SpecNaming.PrintState), Quote("_"
468 + SpecNaming.PrintState.toLowerCase())));
471 // Interface name strings
472 for (File file : interfaceListMap.keySet()) {
473 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
474 for (InterfaceConstruct construct : list) {
475 String name = construct.getName();
476 code.addLine(ShortComment(name + " function strings"));
478 String tmpFunc = name + "_" + SpecNaming.Transition;
479 code.addLine(DeclareDefine(SpecNaming.CString,
480 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
482 tmpFunc = name + "_" + SpecNaming.PreCondition;
483 if (!construct.preCondition.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.SideEffect;
492 if (!construct.sideEffect.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));
500 tmpFunc = name + "_" + SpecNaming.PostCondition;
501 if (!construct.postCondition.isEmpty())
502 code.addLine(DeclareDefine(SpecNaming.CString,
503 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
505 code.addLine(DeclareDefine(SpecNaming.CString,
506 SpecNaming.AppendStr(tmpFunc),
507 SpecNaming.EmptyCString));
509 tmpFunc = name + "_" + SpecNaming.PrintValue;
510 if (!construct.print.isEmpty())
511 code.addLine(DeclareDefine(SpecNaming.CString,
512 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
514 code.addLine(DeclareDefine(SpecNaming.CString,
515 SpecNaming.AppendStr(tmpFunc),
516 SpecNaming.EmptyCString));
522 code.addLine(ShortComment("Define @" + SpecNaming.InitalState));
523 code.addLine("void _" + SpecNaming.InitalState.toLowerCase() + "("
524 + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
525 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
526 + SpecNaming.StateInst, "new " + SpecNaming.StateStruct)));
528 for (VariableDeclaration decl : globalConstruct.declState) {
529 code.addLine(TabbedLine("#define " + decl.name + " "
530 + SpecNaming.StateInst + "->" + decl.name));
532 if (!globalConstruct.autoGenInitial)
533 code.addLine(TabbedLine(ShortComment("User-defined state intialization code")));
535 // Auto-generated the initialization function
536 code.addLine(TabbedLine(ShortComment("Auto-generated state intialization code")));
537 // Align the code with one tab
538 globalConstruct.initState.align(1);
539 code.addLines(globalConstruct.initState);
541 for (VariableDeclaration decl : globalConstruct.declState) {
542 code.addLine(TabbedLine("#undef " + decl.name));
545 code.addLine(TabbedLine(AssignToPtr(SpecNaming.Method1,
546 SpecNaming.StateInst, SpecNaming.StateInst)));
551 code.addLine(ShortComment("Define @" + SpecNaming.CopyState));
552 code.addLine("void _" + SpecNaming.CopyState.toLowerCase() + "("
553 + SpecNaming.Method + " " + "dest, " + SpecNaming.Method
555 // StateStruct *OLD = (StateStruct*) src->state;
556 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
557 + SpecNaming.OldStateInst, Brace(SpecNaming.StateStruct + "*")
558 + " src->" + SpecNaming.StateInst)));
559 // StateStruct *NEW = new StateStruct;
560 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
561 + SpecNaming.NewStateInst, "new " + SpecNaming.StateStruct)));
562 if (!globalConstruct.autoGenCopy)
563 code.addLine(TabbedLine(ShortComment("User-defined state copy statements")));
565 // Auto-generated the copy function
566 code.addLine(TabbedLine(ShortComment("Auto-generated state copy statements")));
567 globalConstruct.copyState.align(1);
568 code.addLines(globalConstruct.copyState);
570 code.addLine(TabbedLine(AssignToPtr("dest", SpecNaming.StateInst,
571 SpecNaming.NewStateInst)));
576 if (!globalConstruct.printState.isEmpty()) {
577 code.addLine(ShortComment("Define @" + SpecNaming.PrintState));
578 code.addLine("void _" + SpecNaming.PrintState.toLowerCase() + "("
579 + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
581 // Initialize state struct fields
582 Code fieldsInit = GenerateStateFieldsInitialization(
583 SpecNaming.Method1, SpecNaming.StateInst, globalConstruct);
585 code.addLines(fieldsInit);
587 if (!globalConstruct.autoGenPrint)
588 code.addLine(TabbedLine(ShortComment("Execute user-defined state printing code")));
590 // Auto-generated the copy function
591 code.addLine(TabbedLine(ShortComment("Execute auto-generated state printing code")));
593 // Align the code with one tab
594 globalConstruct.printState.align(1);
595 code.addLines(globalConstruct.printState);
600 // Define @Commutativity
601 code.addLine(ShortComment("Define commutativity checking functions"));
602 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
603 CommutativityRule rule = globalConstruct.commutativityRules
605 code.addLine("bool _check" + SpecNaming.Commutativity + i + "("
606 + SpecNaming.Method + " m1, " + SpecNaming.Method
608 // if (m1->name == _ENQ_str && m2->name == _DEQ_str) {
609 code.addLine(TabbedLine("if (m1->name == "
610 + SpecNaming.AppendStr(rule.method1) + " && m2->name == "
611 + SpecNaming.AppendStr(rule.method2) + ") {"));
612 // Initialize M1 & M2 in commutativity rule
613 // e.g. ENQ *M1 = (ENQ*) m1->value;
614 code.addLine(TabbedLine(
615 DeclareDefine(rule.method1, "*M1", "(" + rule.method1
616 + "*) m1->value"), 2));
617 code.addLine(TabbedLine(
618 DeclareDefine(rule.method2, "*M2", "(" + rule.method2
619 + "*) m2->value"), 2));
620 code.addLine(TabbedLine("return " + rule.condition + ";", 2));
621 code.addLine(TabbedLine("}"));
622 code.addLine(TabbedLine("return false;"));
628 // Define customized interface functions
629 for (File file : interfaceListMap.keySet()) {
630 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
631 for (InterfaceConstruct construct : list) {
632 Code fieldsInit = null;
634 // Define interface functions
635 String name = construct.getName();
636 code.addLine("/********** " + name
637 + " functions **********/");
638 // Define @Transition for INTERFACE
639 code.addLine(ShortComment("Define @" + SpecNaming.Transition
641 code.addLine("void _" + name + "_" + SpecNaming.Transition
642 + "(" + SpecNaming.Method + " " + SpecNaming.Method1
643 + ", " + SpecNaming.Method + " " + SpecNaming.Method2
646 // Initialize value struct fields
647 fieldsInit = GenerateInterfaceFieldsInitialization(
648 SpecNaming.Method2, "value", construct);
650 code.addLines(fieldsInit);
652 construct.transition.align(1);
653 code.addLine(TabbedLine(ShortComment("Execute Transition")));
654 code.addLines(construct.transition);
659 // Define @PreCondition
660 if (!construct.preCondition.isEmpty()) {
661 code.addLine(ShortComment("Define @"
662 + SpecNaming.PreCondition + " for " + name));
663 code.addLine("bool _" + name + "_"
664 + SpecNaming.PreCondition + "(" + SpecNaming.Method
665 + " " + SpecNaming.Method1 + ") {");
667 // Initialize value struct fields
668 fieldsInit = GenerateInterfaceFieldsInitialization(
669 SpecNaming.Method1, "value", construct);
671 code.addLines(fieldsInit);
673 construct.preCondition.align(1);
674 code.addLine(TabbedLine(ShortComment("Execute PreCondition")));
675 code.addLines(construct.preCondition);
681 // Define @SideEffect
682 if (!construct.sideEffect.isEmpty()) {
683 code.addLine(ShortComment("Define @"
684 + SpecNaming.SideEffect + " for " + name));
685 code.addLine("void _" + name + "_" + SpecNaming.SideEffect
686 + "(" + SpecNaming.Method + " "
687 + SpecNaming.Method1 + ") {");
689 // Initialize value struct fields
690 fieldsInit = GenerateInterfaceFieldsInitialization(
691 SpecNaming.Method1, "value", construct);
693 code.addLines(fieldsInit);
695 construct.sideEffect.align(1);
696 code.addLine(TabbedLine(ShortComment("Execute SideEffect")));
697 code.addLines(construct.sideEffect);
702 // Define @PostCondition
703 if (!construct.postCondition.isEmpty()) {
704 code.addLine(ShortComment("Define @"
705 + SpecNaming.PostCondition + " for " + name));
706 code.addLine("bool _" + name + "_"
707 + SpecNaming.PostCondition + "("
708 + SpecNaming.Method + " " + SpecNaming.Method1
711 // Initialize value struct fields
712 fieldsInit = GenerateInterfaceFieldsInitialization(
713 SpecNaming.Method1, "value", construct);
715 code.addLines(fieldsInit);
717 construct.postCondition.align(1);
718 code.addLine(TabbedLine(ShortComment("Execute PostCondition")));
719 code.addLines(construct.postCondition);
725 if (!construct.print.isEmpty()) {
726 code.addLine(ShortComment("Define @"
727 + SpecNaming.PrintValue + " for " + name));
728 code.addLine("void _" + name + "_" + SpecNaming.PrintValue
729 + "(" + SpecNaming.Method + " "
730 + SpecNaming.Method1 + ") {");
731 // Initialize value struct fields
732 fieldsInit = GenerateInterfaceFieldsInitialization(
733 SpecNaming.Method1, "value", construct);
735 code.addLines(fieldsInit);
737 construct.print.align(1);
738 if (!construct.autoGenPrint)
739 code.addLine(TabbedLine(ShortComment("Execute user-defined value printing code")));
741 // Auto-generated the value printing function
742 code.addLine(TabbedLine(ShortComment("Execute auto-generated value printing code")));
743 code.addLines(construct.print);
751 // Define INIT annotation instrumentation function
752 code.addLine(ShortComment("Define INIT annotation instrumentation function"));
753 code.addLine("void _createInitAnnotation() {");
755 // Init commutativity rules
756 code.addLine(TabbedLine(ShortComment("Init commutativity rules")));
757 code.addLine(TabbedLine(DeclareDefine("int",
758 SpecNaming.CommutativityRuleSizeInst,
759 Integer.toString(globalConstruct.commutativityRules.size()))));
760 String tmp = SpecNaming.NewSize
761 + Brace(SpecNaming.CommutativityRule + ", sizeof"
762 + Brace(SpecNaming.CommutativityRule) + " * "
763 + SpecNaming.CommutativityRuleSizeInst);
764 code.addLine(TabbedLine(DeclareDefine(SpecNaming.CommutativityRule, "*"
765 + SpecNaming.CommutativityRuleInst, tmp)));
766 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
767 CommutativityRule rule = globalConstruct.commutativityRules
769 code.addLine(TabbedLine(ShortComment("Initialize commutativity rule ")
771 // new( &commuteRules[0] )CommutativityRule(_ENQ_str, _DEQ_str,
772 // _Commutativity1_str, _checkCommutativity1)
774 + Brace(" &" + SpecNaming.CommutativityRuleInst + "["
775 + (i - 1) + "] ") + SpecNaming.CommutativityRule
776 + "(" + SpecNaming.AppendStr(rule.method1) + ", "
777 + SpecNaming.AppendStr(rule.method2) + ", "
778 + SpecNaming.AppendStr(SpecNaming.Commutativity + i) + ", "
779 + "_check" + SpecNaming.Commutativity + i + ");";
780 code.addLine(TabbedLine(line));
783 // Initialize AnnoInit
784 code.addLine(TabbedLine(ShortComment("Initialize AnnoInit")));
785 // AnnoInit *init = new AnnoInit(
786 code.addLine(TabbedLine(SpecNaming.AnnoInit + " *"
787 + SpecNaming.AnnoInitInst + " = new " + SpecNaming.AnnoInit
789 // new NamedFunction(_Initial_str, INITIAL, (void*) _initial),
790 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
791 + SpecNaming.AppendStr(SpecNaming.InitalState) + ", "
792 + SpecNaming.InitalState.toUpperCase() + ", " + "(void*) _"
793 + SpecNaming.InitalState.toLowerCase() + "),", 2));
794 // new NamedFunction(_Final_str, FINAL, (void*) NULL_FUNC),
795 line = "new " + SpecNaming.NamedFunction + "("
796 + SpecNaming.AppendStr(SpecNaming.FinalState) + ", "
797 + SpecNaming.FinalState.toUpperCase() + ", " + "(void*) ";
798 if (globalConstruct.finalState.isEmpty()) {
799 line = line + SpecNaming.NullFunc + "),";
801 line = line + "_" + SpecNaming.FinalState.toUpperCase();
803 code.addLine(TabbedLine(line, 2));
804 // new NamedFunction(_Copy_str, COPY, (void*) _copy),
805 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
806 + SpecNaming.AppendStr(SpecNaming.CopyState) + ", "
807 + SpecNaming.CopyState.toUpperCase() + ", " + "(void*) _"
808 + SpecNaming.CopyState.toLowerCase() + "),", 2));
809 // new NamedFunction(_Print_str, PRINT_STATE, (void*) _print),
810 line = "new " + SpecNaming.NamedFunction + "("
811 + SpecNaming.AppendStr(SpecNaming.PrintState) + ", "
812 + SpecNaming.PrintStateType + ", " + "(void*)";
813 if (globalConstruct.printState.isEmpty()) {
814 line = line + SpecNaming.NullFunc + "),";
816 line = line + "_" + SpecNaming.PrintState.toLowerCase() + "),";
818 code.addLine(TabbedLine(line, 2));
819 // commuteRules, CommuteRuleSize);
820 code.addLine(TabbedLine(SpecNaming.CommutativityRuleInst + ", "
821 + SpecNaming.CommutativityRuleSizeInst + ");", 2));
824 // Declare StateFunctions map
825 code.addLine(TabbedLine(ShortComment("Declare StateFunctions map")));
826 code.addLine(TabbedLine(Declare(SpecNaming.StateFunctions, "*"
827 + SpecNaming.StateFunctionsInst)));
830 // StateFunction for interface
831 for (File file : interfaceListMap.keySet()) {
832 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
833 for (InterfaceConstruct construct : list) {
834 String name = construct.getName();
835 code.addLine(TabbedLine(ShortComment("StateFunction for "
837 // stateFuncs = new StateFunctions(
838 code.addLine(TabbedLine(SpecNaming.StateFunctionsInst
839 + " = new " + SpecNaming.StateFunctions + "("));
840 // new NamedFunction(_ENQ_Transition_str, TRANSITION, (void*)
843 code.addLine(TabbedLine(
845 + SpecNaming.NamedFunction
847 + SpecNaming.AppendStr(name + "_"
848 + SpecNaming.Transition) + ", "
849 + SpecNaming.TransitionType + ", (void*) _"
850 + name + "_" + SpecNaming.Transition + "),", 2));
853 + SpecNaming.NamedFunction
855 + SpecNaming.AppendStr(name + "_"
856 + SpecNaming.PreCondition) + ", "
857 + SpecNaming.PreConditionType + ", (void*) ";
858 if (construct.preCondition.isEmpty()) {
859 line = line + SpecNaming.NullFunc + "),";
861 line = line + "_" + name + "_" + SpecNaming.PreCondition
864 code.addLine(TabbedLine(line, 2));
867 + SpecNaming.NamedFunction
869 + SpecNaming.AppendStr(name + "_"
870 + SpecNaming.SideEffect) + ", "
871 + SpecNaming.SideEffectType + ", (void*) ";
872 if (construct.sideEffect.isEmpty()) {
873 line = line + SpecNaming.NullFunc + "),";
875 line = line + "_" + name + "_" + SpecNaming.SideEffect
878 code.addLine(TabbedLine(line, 2));
881 + SpecNaming.NamedFunction
883 + SpecNaming.AppendStr(name + "_"
884 + SpecNaming.PostCondition) + ", "
885 + SpecNaming.PostConditionType + ", (void*) ";
886 if (construct.postCondition.isEmpty()) {
887 line = line + SpecNaming.NullFunc + "),";
889 line = line + "_" + name + "_" + SpecNaming.PostCondition
892 code.addLine(TabbedLine(line, 2));
895 + SpecNaming.NamedFunction
897 + SpecNaming.AppendStr(name + "_"
898 + SpecNaming.PrintValue) + ", "
899 + SpecNaming.PrintValueType + ", (void*) ";
900 if (construct.print.isEmpty()) {
901 line = line + SpecNaming.NullFunc + ")";
903 line = line + "_" + name + "_" + SpecNaming.PrintValue
906 code.addLine(TabbedLine(line, 2));
907 code.addLine(TabbedLine(");"));
909 // init->addInterfaceFunctions(_ENQ_str, stateFuncs);
910 code.addLine(TabbedLine(SpecNaming.AnnoInitInst
912 + SpecNaming.AddInterfaceFunctions
913 + Brace(SpecNaming.AppendStr(name) + ", "
914 + SpecNaming.StateFunctionsInst) + ";"));
919 // Create and instrument with the INIT annotation
920 code.addLine(TabbedLine(ShortComment("Create and instrument with the INIT annotation")));
921 // cdsannotate(SPEC_ANALYSIS, new SpecAnnotation(INIT, init));
922 code.addLine(TabbedLine(SpecNaming.CDSAnnotateFunc
923 + Brace(SpecNaming.SPEC_ANALYSIS
925 + SpecNaming.SpecAnnotation
926 + Brace(SpecNaming.AnnoTypeInit + ", "
927 + SpecNaming.AnnoInitInst)) + ";"));
937 * This function generates a list of lines that initialize the fields of the
938 * global state struct. See below.
943 * StateStruct *state = (StateStruct*) _M->state;
945 * IntList * q = state->q;
950 * In this example, _M --> methodInst, state --> inst.
958 * The global state construct
959 * @return The generated code
961 public static Code GenerateStateFieldsInitialization(String methodInst,
962 String inst, GlobalConstruct construct) {
963 Code res = new Code();
964 res.addLine(ShortComment("Initialize " + SpecNaming.StateStruct
966 res.addLine(DeclareDefine(SpecNaming.StateStruct, "*" + inst, "("
967 + SpecNaming.StateStruct + "*) " + methodInst + "->state"));
968 for (VariableDeclaration decl : construct.declState) {
969 res.addLine(DeclareDefine(decl.type, decl.name, inst + "->"
977 * This function generates a list of lines that initialize the fields of a
978 * specific interface struct. See below.
983 * ENQ *info = (ENQ*) _M->value;
985 * IntList * q = info->q;
990 * In this example, ENQ --> structType, _M --> methodInst, info --> inst
998 * The corresponding interface construct
999 * @return The generated code
1001 public static Code GenerateInterfaceFieldsInitialization(String methodInst,
1002 String inst, InterfaceConstruct construct) {
1003 Code res = new Code();
1004 String name = construct.getName();
1005 res.addLine(ShortComment("Initialize fields for " + name));
1006 // The very first assignment "
1007 res.addLine(DeclareDefine(name, "*" + inst, "(" + name + "*) "
1008 + methodInst + "->value"));
1009 // Don't leave out the RET field
1010 if (!construct.getFunctionHeader().isReturnVoid()) {
1011 res.addLine(DeclareDefine(construct.getFunctionHeader().returnType,
1012 SpecNaming.RET, "value->" + SpecNaming.RET));
1015 for (VariableDeclaration decl : construct.getFunctionHeader().args) {
1016 res.addLine(DeclareDefine(decl.type, decl.name, inst + "->"
1024 * This function generates the code to be inserted right after the ordering
1025 * point construct (instrumentation code)
1029 * The corresponding ordering point construct
1030 * @return The generated code
1032 public static Code Generate4OPConstruct(OPConstruct construct) {
1033 Code code = new Code();
1034 String curLine = construct.annotation;
1035 String label = construct.label;
1036 String prefixTabs = curLine.substring(0, curLine.indexOf("/**"));
1037 code.addLine(prefixTabs + "if (" + construct.condition + ")");
1038 switch (construct.type) {
1040 code.addLine(prefixTabs + "\t" + SpecNaming.CreateOPDefineAnnoFunc
1044 code.addLine(prefixTabs + "\t"
1045 + SpecNaming.CreatePotentialOPAnnoFunc + "("
1046 + SpecNaming.AppendStr(label) + ");");
1049 code.addLine(prefixTabs + "\t" + SpecNaming.CreateOPCheckAnnoFunc
1050 + "(" + SpecNaming.AppendStr(label) + ");");
1053 code.addLine(prefixTabs + "\t" + SpecNaming.CreateOPClearAnnoFunc
1057 code.addLine(prefixTabs + "\t"
1058 + SpecNaming.CreateOPClearDefineAnnoFunc + "();");
1068 * This function generates the code to be inserted right after the entry
1069 * construct (instrumentation code)
1073 * The corresponding entry construct
1076 public static Code Generate4Entry(EntryConstruct construct) {
1077 Code res = new Code();
1078 String curLine = construct.annotation;
1079 String prefixTabs = curLine.substring(0, curLine.indexOf("/**"));
1080 // _createInitAnnotation();
1081 res.addLine(prefixTabs + SpecNaming.CreateInitAnnoFunc + "();");
1087 * This function generates the code to be inserted right after the "@Define"
1088 * construct (instrumentation code)
1092 * The corresponding entry construct
1095 public static Code Generate4Define(DefineConstruct construct) {
1096 Code code = new Code();
1098 code.addLine("/********** User-defined code in annotation (BEGIN) **********/");
1099 code.addLines(construct.code);
1100 code.addLine("/********** User-defined code in annotation (END) **********/");
1106 * This function generates the new interface wrapper code to be inserted
1107 * right after the end of the interface definition
1111 * The corresponding interface construct
1112 * @return The generated code
1114 public static Code GenerateInterfaceWrapper(InterfaceConstruct construct) {
1115 Code code = new Code();
1117 String name = construct.getName();
1118 String beginLine = construct.getFunctionHeader().getHeaderLine();
1119 Pattern regexpSpace = Pattern.compile("^(\\s*)\\S.*$");
1120 Matcher matcherSpace = regexpSpace.matcher(beginLine);
1121 String prefixTabs = "";
1122 if (matcherSpace.find())
1123 prefixTabs = matcherSpace.group(1);
1125 // Add one line to separate
1127 code.addLine(prefixTabs
1128 + ShortComment("Generated wrapper interface for " + name));
1129 if (beginLine.indexOf('{') == -1) { // We need to add the '{' to the end
1131 code.addLine(beginLine + " {");
1133 code.addLine(beginLine);
1135 // Instrument with the INTERFACE_BEGIN annotations
1136 code.addLine(prefixTabs
1138 + ShortComment("Instrument with the INTERFACE_BEGIN annotation"));
1139 // CAnnoInterfaceInfo info = _createInterfaceBeginAnnotation(_DEQ_str);
1140 code.addLine(prefixTabs
1142 + DeclareDefine(SpecNaming.AnnoInterfaceInfo, "*"
1143 + SpecNaming.AnnoInterfaceInfoInst,
1144 SpecNaming.CreateInterfaceBeginAnnoFunc
1145 + Brace(SpecNaming.AppendStr(name))));
1146 // Call the actual function
1147 code.addLine(prefixTabs + "\t"
1148 + ShortComment("Call the actual function"));
1149 // bool RET = dequeue_ORIGINAL__(q, retVal, reclaimNode);
1150 code.addLine(prefixTabs + "\t"
1151 + construct.getFunctionHeader().getRenamedCall() + ";");
1154 // Initialize the value struct
1155 code.addLine(prefixTabs + "\t"
1156 + ShortComment("Initialize the value struct"));
1157 // The very first assignment "
1158 code.addLine(prefixTabs + "\t"
1159 + DeclareDefine(name, "*value", SpecNaming.New + Brace(name)));
1160 // Don't leave out the RET field
1161 if (!construct.getFunctionHeader().isReturnVoid())
1162 code.addLine(prefixTabs + "\t"
1163 + AssignToPtr("value", SpecNaming.RET, SpecNaming.RET));
1165 for (VariableDeclaration decl : construct.getFunctionHeader().args)
1166 code.addLine(prefixTabs + "\t"
1167 + AssignToPtr("value", decl.name, decl.name));
1170 // Store the value info into the current MethodCall
1171 // _setInterfaceBeginAnnotationValue(info, value);
1172 code.addLine(prefixTabs
1174 + ShortComment("Store the value info into the current MethodCall"));
1175 code.addLine(prefixTabs + "\t"
1176 + SpecNaming.SetInterfaceBeginAnnoValueFunc
1177 + Brace(SpecNaming.AnnoInterfaceInfoInst + ", value") + ";");
1180 // Return if necessary
1181 if (!construct.getFunctionHeader().isReturnVoid())
1182 code.addLine(prefixTabs + "\treturn " + SpecNaming.RET + ";");
1183 code.addLine(prefixTabs + "}");
1190 * Write a list of lines (as the whole of the file) to a file ---
1191 * newFileName. If that file does not exist, we create that file and then
1195 * @param newFileName
1196 * The name of the file to be written
1198 * The list of lines that as a whole become the content of the
1201 public static void write2File(String newFileName, ArrayList<String> content) {
1202 File newFile = new File(newFileName);
1203 newFile.getParentFile().mkdirs();
1204 if (!newFile.exists()) {
1206 newFile.createNewFile();
1207 } catch (IOException e) {
1208 e.printStackTrace();
1211 BufferedWriter bw = null;
1213 bw = new BufferedWriter(new FileWriter(newFile));
1214 for (int i = 0; i < content.size(); i++) {
1215 bw.write(content.get(i) + "\n");
1218 } catch (IOException e) {
1219 e.printStackTrace();
1224 } catch (IOException e) {
1225 e.printStackTrace();