Mercurial > hg > CbC > CbC_xv6
comparison src/gearsTools/generate_context.pl @ 45:5f19e9554c30
supless warning
author | k.fukuda |
---|---|
date | Sun, 03 Mar 2019 17:39:05 +0900 |
parents | |
children | 9647d79fe97e |
comparison
equal
deleted
inserted
replaced
43:b94d72292dfa | 45:5f19e9554c30 |
---|---|
1 #!/usr/bin/perl | |
2 | |
3 use Getopt::Std; | |
4 use strict; | |
5 | |
6 # | |
7 # generrate Gears OS context heaader and initializer from CbC sources | |
8 # | |
9 # CodeGear | |
10 # | |
11 # get stub information from # *.c | |
12 # __code taskManager_stub(struct Context* context) { | |
13 # | |
14 # generate CodeGear indexn in context.h | |
15 # C_taskManager, | |
16 # | |
17 # generate CodeGear stub reference in context.h | |
18 # extern __code taskManager_stub(struct Context*); | |
19 # | |
20 # generate CodeGear stub reference in $name-context.h for each module | |
21 # context->code[C_taskManager] = taskManager_stub; | |
22 # | |
23 # DataGear | |
24 # | |
25 # get DataGear information from context.h | |
26 # struct Worker { | |
27 # int id; | |
28 # struct Context* contexts; | |
29 # enum Code execute; | |
30 # enum Code taskSend; | |
31 # enum Code taskRecive; | |
32 # enum Code shutdown; | |
33 # struct Queue* tasks; | |
34 # } Worker; | |
35 # | |
36 # generate typedefs and DataGear index in context.h | |
37 # typedef struct Worker Worker; | |
38 # D_Worker, | |
39 # | |
40 # generate DataGear allocator in context.h | |
41 # ALLOC_DATA(context, Worker); | |
42 # | |
43 | |
44 my $ddir = "c"; | |
45 | |
46 our($opt_o,$opt_d,$opt_h); | |
47 getopts('o:d:h'); | |
48 | |
49 my $name = $opt_o?$opt_o:"gears"; | |
50 | |
51 if ($opt_d) { | |
52 $ddir = $opt_d; | |
53 } | |
54 | |
55 if ( ! -d $ddir) { | |
56 mkdir $ddir; | |
57 } | |
58 | |
59 if ($opt_h) { | |
60 print "$0 [-d distdir] [-h]\n"; | |
61 exit; | |
62 } | |
63 | |
64 my %codeGear; | |
65 my %dataGear; | |
66 my %constructor; | |
67 | |
68 # gather module Information for code table initialization | |
69 for (@ARGV) { | |
70 next if (/context.c/); | |
71 &getStubInfo($_); | |
72 } | |
73 | |
74 my (%mCodeGear) = (%codeGear); | |
75 | |
76 # anyway we gather all Gears Information | |
77 while (<*.c test/*.c>) { | |
78 next if (/context.c/); | |
79 &getStubInfo($_); | |
80 } | |
81 | |
82 &generateContext(); | |
83 | |
84 sub getStubInfo { | |
85 my ($filename) = @_; | |
86 open my $fd,"<",$filename or die("can't open $filename $!"); | |
87 while (<$fd>) { | |
88 if (/^__code (\w+)_stub\(struct *Context *\* *context\)/) { | |
89 $codeGear{$1} = $filename; | |
90 } elsif (/^(\w+)(\*)+ *create(\w+)\(([^]]*)\)/) { | |
91 my $interface = $1; | |
92 my $implementation = $3; | |
93 my $constructorArgs = $4; | |
94 $constructor{$implementation} = [$interface, $constructorArgs]; | |
95 } | |
96 } | |
97 | |
98 open my $cx,"<","context.h" or die("can't open context.h $!"); | |
99 my $inUnionData = 0; | |
100 while (<$cx>) { | |
101 if (! $inUnionData) { | |
102 if ( /^union Data/) { | |
103 $inUnionData = 1; | |
104 } | |
105 next; | |
106 } | |
107 last if (/union Data end/); | |
108 if (/struct (\w+) \{/) { | |
109 $dataGear{$1} = 'struct'; | |
110 } elsif (/^\s{4}(\w+) (\w+);/) { # primitive type | |
111 $dataGear{$1} = 'primitive'; | |
112 } | |
113 $dataGear{"Context"} = "struct"; | |
114 } | |
115 } | |
116 | |
117 sub generateContext { | |
118 $codeGear{"start_code"} = "$ddir/$name-context.c"; | |
119 $codeGear{"exit_code"} = "$ddir/$name-context.c"; | |
120 $mCodeGear{"start_code"} = "$ddir/$name-context.c"; | |
121 $mCodeGear{"exit_code"} = "$ddir/$name-context.c"; | |
122 open my $fd,">","$ddir/extern.h" or die("can't open $ddir/extern.h $!"); | |
123 for my $code ( sort keys %codeGear ) { | |
124 print $fd "extern __code ${code}_stub(struct Context*);\n"; | |
125 } | |
126 for my $impl ( sort keys %constructor ) { | |
127 my ($interface, $constructorArgs) = @{$constructor{$impl}}; | |
128 print $fd "extern ${interface}* create${impl}($constructorArgs);\n"; | |
129 } | |
130 print $fd "\n"; | |
131 | |
132 open my $fd,">","$ddir/enumCode.h" or die("can't open $ddir/enumCode.h $!"); | |
133 print $fd "enum Code {\n"; | |
134 for my $code ( sort keys %codeGear ) { | |
135 print $fd " C_${code},\n"; | |
136 } | |
137 print $fd "};\n"; | |
138 | |
139 my $code_init = ''; | |
140 for my $code ( sort keys %mCodeGear ) { | |
141 $code_init .= " context->code[C_${code}] = ${code}_stub;\n"; | |
142 } | |
143 | |
144 my $data_num = keys(%dataGear); | |
145 $data_num++; | |
146 my $context_c = << "EOFEOF"; | |
147 #include <stdlib.h> | |
148 | |
149 #include "../context.h" | |
150 | |
151 void initContext(struct Context* context) { | |
152 context->heapLimit = sizeof(union Data)*ALLOCATE_SIZE; | |
153 context->code = (__code(**) (struct Context*)) NEWN(ALLOCATE_SIZE, void*); | |
154 context->data = NEWN(ALLOCATE_SIZE, union Data*); | |
155 context->heapStart = NEWN(context->heapLimit, char); | |
156 context->heap = context->heapStart; | |
157 // context->codeNum = Exit; | |
158 | |
159 $code_init | |
160 | |
161 #include "dataGearInit.c" | |
162 context->dataNum = $data_num; | |
163 } | |
164 EOFEOF | |
165 | |
166 open my $fd,">","$ddir/$name-context.c" or die("can't open $ddir/$name-context.c $!"); | |
167 print $fd $context_c; | |
168 | |
169 my $meta_call = <<"EOFEOF"; | |
170 __code meta(struct Context* context, enum Code next) { | |
171 // printf("meta %d\\n",next); | |
172 goto (context->code[next])(context); | |
173 } | |
174 | |
175 __code parGotoMeta(struct Context* context, enum Code next) { | |
176 context->task = NULL; | |
177 context->taskList = NULL; | |
178 goto (context->code[Gearef(context, TaskManager)->taskManager->TaskManager.spawnTasks])(context); | |
179 } | |
180 | |
181 __code start_code(struct Context* context) { | |
182 goto meta(context, context->next); | |
183 } | |
184 | |
185 __code start_code_stub(struct Context* context) { | |
186 goto start_code(context); | |
187 } | |
188 | |
189 __code exit_code(struct Context* context) { | |
190 free(context->code); | |
191 free(context->data); | |
192 free(context->heapStart); | |
193 goto exit(0); | |
194 } | |
195 | |
196 __code exit_code_stub(struct Context* context) { | |
197 goto exit_code(context); | |
198 } | |
199 | |
200 // end context_c | |
201 EOFEOF | |
202 | |
203 print $fd $meta_call; | |
204 | |
205 open my $fd,">","$ddir/enumData.h" or die("can't open $ddir/enumData.h $!"); | |
206 print $fd "enum DataType {\n"; | |
207 print $fd " D_Code,\n"; | |
208 for my $data ( sort keys %dataGear ) { | |
209 print $fd " D_${data},\n"; | |
210 } | |
211 print $fd "};\n\n"; | |
212 | |
213 open my $fd,">","$ddir/typedefData.h" or die("can't open $ddir/typedefData.h $!"); | |
214 for my $data ( sort keys %dataGear ) { | |
215 if ($dataGear{$data} eq 'struct') { | |
216 print $fd "typedef struct ${data} ${data};\n"; | |
217 } | |
218 } | |
219 | |
220 open my $fd,">","$ddir/dataGearInit.c" or die("can't open $ddir/dataGearInit.c $!"); | |
221 for my $data ( sort keys %dataGear ) { | |
222 print $fd " ALLOC_DATA(context, ${data});\n"; | |
223 } | |
224 } | |
225 | |
226 # end |