Branch data Line data Source code
1 : : /* do not edit automatically generated by mc from M2Scaffold. */
2 : : /* M2Scaffold.mod declare and create scaffold entities.
3 : :
4 : : Copyright (C) 2022-2024 Free Software Foundation, Inc.
5 : : Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 : :
7 : : This file is part of GNU Modula-2.
8 : :
9 : : GNU Modula-2 is free software; you can redistribute it and/or modify
10 : : it under the terms of the GNU General Public License as published by
11 : : the Free Software Foundation; either version 3, or (at your option)
12 : : any later version.
13 : :
14 : : GNU Modula-2 is distributed in the hope that it will be useful, but
15 : : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : General Public License for more details.
18 : :
19 : : You should have received a copy of the GNU General Public License
20 : : along with GNU Modula-2; see the file COPYING3. If not see
21 : : <http://www.gnu.org/licenses/>. */
22 : :
23 : : #include "config.h"
24 : : #include "system.h"
25 : : #include <stdbool.h>
26 : : # if !defined (PROC_D)
27 : : # define PROC_D
28 : : typedef void (*PROC_t) (void);
29 : : typedef struct { PROC_t proc; } PROC;
30 : : # endif
31 : :
32 : : # if !defined (TRUE)
33 : : # define TRUE (1==1)
34 : : # endif
35 : :
36 : : # if !defined (FALSE)
37 : : # define FALSE (1==0)
38 : : # endif
39 : :
40 : : #if defined(__cplusplus)
41 : : # undef NULL
42 : : # define NULL 0
43 : : #endif
44 : : #define _M2Scaffold_H
45 : : #define _M2Scaffold_C
46 : :
47 : : # include "GSymbolTable.h"
48 : : # include "GNameKey.h"
49 : : # include "GM2Base.h"
50 : : # include "GM2System.h"
51 : : # include "GM2LexBuf.h"
52 : : # include "GAssertion.h"
53 : : # include "GLists.h"
54 : : # include "GM2MetaError.h"
55 : : # include "GM2Search.h"
56 : : # include "GSFIO.h"
57 : : # include "GFIO.h"
58 : : # include "GFormatStrings.h"
59 : : # include "GM2Options.h"
60 : : # include "GM2Quads.h"
61 : : # include "GM2Batch.h"
62 : : # include "GM2Printf.h"
63 : : # include "GDynamicStrings.h"
64 : : # include "GM2Graph.h"
65 : :
66 : : unsigned int M2Scaffold_mainFunction;
67 : : unsigned int M2Scaffold_initFunction;
68 : : unsigned int M2Scaffold_finiFunction;
69 : : unsigned int M2Scaffold_linkFunction;
70 : : unsigned int M2Scaffold_ctorArray;
71 : : # define Comment '#'
72 : : # define Debugging false
73 : : static Lists_List uselistModules;
74 : : static Lists_List ctorModules;
75 : : static Lists_List ctorGlobals;
76 : : static unsigned int ctorArrayType;
77 : : static bool initialized;
78 : : static unsigned int ctorTok;
79 : :
80 : : /*
81 : : DeclareScaffold - declare scaffold related entities.
82 : : */
83 : :
84 : : extern "C" void M2Scaffold_DeclareScaffold (unsigned int tokno);
85 : :
86 : : /*
87 : : DeclareArgEnvParams - declares (int argc, void *argv, void *envp)
88 : : */
89 : :
90 : : extern "C" void M2Scaffold_DeclareArgEnvParams (unsigned int tokno, unsigned int proc);
91 : :
92 : : /*
93 : : PopulateCtorArray - assign each element of the ctorArray to the external module ctor.
94 : : This is only used to force the linker to pull in the ctors from
95 : : a library.
96 : : */
97 : :
98 : : extern "C" void M2Scaffold_PopulateCtorArray (unsigned int tok);
99 : :
100 : : /*
101 : : ForeachModuleCallInit - is only called when -fscaffold-static is enabled.
102 : : precondition: the module list will be ordered.
103 : : postcondition: foreach module in the application universe
104 : : call _M2_module_init (argc, argv, envp);
105 : : */
106 : :
107 : : extern "C" void M2Scaffold_ForeachModuleCallInit (unsigned int tok, unsigned int argc, unsigned int argv, unsigned int envp);
108 : :
109 : : /*
110 : : ForeachModuleCallFinish - precondition: the module list will be ordered.
111 : : postcondition: foreach module in the application universe
112 : : call _M2_module_fini (argc, argv, envp);
113 : : */
114 : :
115 : : extern "C" void M2Scaffold_ForeachModuleCallFinish (unsigned int tok, unsigned int argc, unsigned int argv, unsigned int envp);
116 : :
117 : : /*
118 : : DeclareCtorArrayType - declare an ARRAY [0..high] OF PROC which will
119 : : be used to reference every module ctor.
120 : : */
121 : :
122 : : static unsigned int DeclareCtorArrayType (unsigned int tokenno, unsigned int high);
123 : :
124 : : /*
125 : : DeclareCtorGlobal - declare the ctorArray variable.
126 : : */
127 : :
128 : : static void DeclareCtorGlobal (unsigned int tokenno);
129 : :
130 : : /*
131 : : LookupModuleSym - returns a defimp module. It looks up an existing
132 : : module and if this does not exist creates a new one.
133 : : */
134 : :
135 : : static unsigned int LookupModuleSym (unsigned int tok, NameKey_Name name);
136 : :
137 : : /*
138 : : addDependentStatement -
139 : : */
140 : :
141 : : static void addDependentStatement (M2Graph_Graph graph, unsigned int moduleSym, Lists_List list);
142 : :
143 : : /*
144 : : addDependentImport - adds dependent imports of moduleSym into the graph.
145 : : */
146 : :
147 : : static void addDependentImport (M2Graph_Graph graph, unsigned int moduleSym, Lists_List importList);
148 : :
149 : : /*
150 : : TopologicallySortList - topologically sort the list based on import graph.
151 : : A new list is returned.
152 : : */
153 : :
154 : : static Lists_List TopologicallySortList (Lists_List list, unsigned int topModule);
155 : :
156 : : /*
157 : : AddEntry - adds an entry to the ctorGlobals and uselistModules.
158 : : */
159 : :
160 : : static void AddEntry (unsigned int tok, NameKey_Name name);
161 : :
162 : : /*
163 : : ReadModules - populate ctorGlobals with the modules specified by -fuse-list=filename.
164 : : */
165 : :
166 : : static void ReadModules (unsigned int tok, DynamicStrings_String filename);
167 : :
168 : : /*
169 : : AddModuleToCtor - adds moduleSym to the uselistModules and
170 : : sets all modules ctors as extern.
171 : : */
172 : :
173 : : static void AddModuleToCtor (unsigned int moduleSym);
174 : :
175 : : /*
176 : : WriteList - writes the list to GetGenModuleFilename
177 : : providing the filename is not NIL and not '-'.
178 : : */
179 : :
180 : : static void WriteList (unsigned int tok, Lists_List list);
181 : :
182 : : /*
183 : : CreateCtorListFromImports - if GenModuleList then populate
184 : : the ctor list from all modules which are
185 : : not FOR 'C'.
186 : : */
187 : :
188 : : static bool CreateCtorListFromImports (unsigned int tok);
189 : :
190 : : /*
191 : : CreateCtorList - uses GetUselistFilename and then reads the list of modules.
192 : : */
193 : :
194 : : static bool CreateCtorList (unsigned int tok);
195 : :
196 : : /*
197 : : DeclareModuleExtern - declare the extern _M2_modulename_ctor, _M2_modulename_init,
198 : : _M2_modulename_fini, _M2_modulename_dep for each external module.
199 : : */
200 : :
201 : : static void DeclareModuleExtern (unsigned int tokenno);
202 : :
203 : : /*
204 : : DeclareScaffoldFunctions - declare main, _M2_init,_M2_finish
205 : : and _M2_link to the modula-2
206 : : front end.
207 : : */
208 : :
209 : : static void DeclareScaffoldFunctions (unsigned int tokenno);
210 : :
211 : :
212 : : /*
213 : : DeclareCtorArrayType - declare an ARRAY [0..high] OF PROC which will
214 : : be used to reference every module ctor.
215 : : */
216 : :
217 : 2390 : static unsigned int DeclareCtorArrayType (unsigned int tokenno, unsigned int high)
218 : : {
219 : 2390 : unsigned int subscript;
220 : 2390 : unsigned int subrange;
221 : :
222 : : /* ctorArrayType = ARRAY [0..n] OF PROC ; */
223 : 2390 : ctorArrayType = SymbolTable_MakeArray (tokenno, NameKey_MakeKey ((const char *) "ctorGlobalType", 14));
224 : 2390 : SymbolTable_PutArray (ctorArrayType, M2Base_Proc);
225 : 2390 : subrange = SymbolTable_MakeSubrange (tokenno, NameKey_NulName);
226 : 2390 : SymbolTable_PutSubrange (subrange, SymbolTable_MakeConstant (tokenno, 0), SymbolTable_MakeConstant (tokenno, high), M2Base_Cardinal);
227 : 2390 : subscript = SymbolTable_MakeSubscript ();
228 : 2390 : SymbolTable_PutSubscript (subscript, subrange);
229 : 2390 : SymbolTable_PutArraySubscript (ctorArrayType, subscript);
230 : 2390 : return ctorArrayType;
231 : : /* static analysis guarentees a RETURN statement will be used before here. */
232 : : __builtin_unreachable ();
233 : : }
234 : :
235 : :
236 : : /*
237 : : DeclareCtorGlobal - declare the ctorArray variable.
238 : : */
239 : :
240 : 2390 : static void DeclareCtorGlobal (unsigned int tokenno)
241 : : {
242 : 2390 : unsigned int n;
243 : :
244 : 2390 : n = Lists_NoOfItemsInList (ctorGlobals);
245 : 2390 : ctorArrayType = DeclareCtorArrayType (tokenno, n);
246 : 2390 : M2Scaffold_ctorArray = SymbolTable_MakeVar (tokenno, NameKey_MakeKey ((const char *) "_M2_ctorArray", 13));
247 : 2390 : SymbolTable_PutVar (M2Scaffold_ctorArray, ctorArrayType);
248 : 2390 : }
249 : :
250 : :
251 : : /*
252 : : LookupModuleSym - returns a defimp module. It looks up an existing
253 : : module and if this does not exist creates a new one.
254 : : */
255 : :
256 : 0 : static unsigned int LookupModuleSym (unsigned int tok, NameKey_Name name)
257 : : {
258 : 0 : unsigned int sym;
259 : 0 : DynamicStrings_String FileName;
260 : 0 : DynamicStrings_String LibName;
261 : :
262 : 0 : sym = M2Batch_Get (name);
263 : 0 : if (sym == SymbolTable_NulSym)
264 : : {
265 : 0 : LibName = static_cast<DynamicStrings_String> (NULL);
266 : 0 : FileName = static_cast<DynamicStrings_String> (NULL);
267 : 0 : if (M2Search_FindSourceDefFile (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (name)), &FileName, &LibName))
268 : : {
269 : : /* avoid dangling else. */
270 : 0 : sym = SymbolTable_MakeDefImp (tok, name);
271 : 0 : SymbolTable_PutLibName (sym, NameKey_makekey (DynamicStrings_string (LibName)));
272 : 0 : if (sym != (SymbolTable_GetMainModule ()))
273 : : {
274 : 0 : SymbolTable_PutModuleCtorExtern (tok, sym, ! M2Options_WholeProgram);
275 : : }
276 : : }
277 : : else
278 : : {
279 : 0 : M2MetaError_MetaErrorStringT0 (tok, FormatStrings_Sprintf1 (DynamicStrings_InitString ((const char *) "the definition module file for {%%1a} cannot be found", 53), (const unsigned char *) &name, (sizeof (name)-1)));
280 : : }
281 : : }
282 : 0 : return sym;
283 : : /* static analysis guarentees a RETURN statement will be used before here. */
284 : : __builtin_unreachable ();
285 : : }
286 : :
287 : :
288 : : /*
289 : : addDependentStatement -
290 : : */
291 : :
292 : 207448 : static void addDependentStatement (M2Graph_Graph graph, unsigned int moduleSym, Lists_List list)
293 : : {
294 : 207448 : NameKey_Name n1;
295 : 207448 : NameKey_Name n2;
296 : 207448 : unsigned int import;
297 : 207448 : unsigned int depmod;
298 : 207448 : unsigned int i;
299 : 207448 : unsigned int n;
300 : :
301 : 207448 : n = Lists_NoOfItemsInList (list);
302 : 207448 : i = 1;
303 : 626748 : while (i <= n)
304 : : {
305 : 211852 : import = static_cast<unsigned int> (Lists_GetItemFromList (list, i));
306 : 211852 : Assertion_Assert (SymbolTable_IsImport (import));
307 : 211852 : depmod = SymbolTable_GetImportModule (import);
308 : 211852 : M2Graph_AddDependent (graph, moduleSym, depmod);
309 : 211852 : if (Debugging)
310 : : {
311 : : n1 = SymbolTable_GetSymName (moduleSym);
312 : : n2 = SymbolTable_GetSymName (depmod);
313 : : M2Printf_printf2 ((const char *) "AddDependent (%a, %a)\\n", 23, (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
314 : : }
315 : 211852 : i += 1;
316 : : }
317 : 207448 : }
318 : :
319 : :
320 : : /*
321 : : addDependentImport - adds dependent imports of moduleSym into the graph.
322 : : */
323 : :
324 : 114516 : static void addDependentImport (M2Graph_Graph graph, unsigned int moduleSym, Lists_List importList)
325 : : {
326 : 114516 : unsigned int stmt;
327 : 114516 : unsigned int i;
328 : 114516 : unsigned int n;
329 : :
330 : 114516 : n = Lists_NoOfItemsInList (importList);
331 : 114516 : i = 1;
332 : 436480 : while (i <= n)
333 : : {
334 : 207448 : stmt = static_cast<unsigned int> (Lists_GetItemFromList (importList, i));
335 : 207448 : Assertion_Assert (SymbolTable_IsImportStatement (stmt));
336 : 207448 : addDependentStatement (graph, moduleSym, SymbolTable_GetImportStatementList (stmt));
337 : 207448 : i += 1;
338 : : }
339 : 114516 : }
340 : :
341 : :
342 : : /*
343 : : TopologicallySortList - topologically sort the list based on import graph.
344 : : A new list is returned.
345 : : */
346 : :
347 : 2390 : static Lists_List TopologicallySortList (Lists_List list, unsigned int topModule)
348 : : {
349 : 2390 : M2Graph_Graph graph;
350 : 2390 : unsigned int i;
351 : 2390 : unsigned int n;
352 : 2390 : unsigned int moduleSym;
353 : :
354 : 2390 : graph = M2Graph_InitGraph ();
355 : 2390 : n = Lists_NoOfItemsInList (list);
356 : 2390 : i = 1;
357 : 59648 : while (i <= n)
358 : : {
359 : 54868 : moduleSym = static_cast<unsigned int> (Lists_GetItemFromList (uselistModules, i));
360 : 54868 : addDependentImport (graph, moduleSym, SymbolTable_GetModuleDefImportStatementList (moduleSym));
361 : 54868 : addDependentImport (graph, moduleSym, SymbolTable_GetModuleModImportStatementList (moduleSym));
362 : 54868 : i += 1;
363 : : }
364 : : /* Ensure that topModule is also in the graph. */
365 : 2390 : if (! (Lists_IsItemInList (list, topModule)))
366 : : {
367 : 2390 : addDependentImport (graph, topModule, SymbolTable_GetModuleDefImportStatementList (topModule));
368 : 2390 : addDependentImport (graph, topModule, SymbolTable_GetModuleModImportStatementList (topModule));
369 : : }
370 : 2390 : return M2Graph_SortGraph (graph, topModule);
371 : : /* static analysis guarentees a RETURN statement will be used before here. */
372 : : __builtin_unreachable ();
373 : : }
374 : :
375 : :
376 : : /*
377 : : AddEntry - adds an entry to the ctorGlobals and uselistModules.
378 : : */
379 : :
380 : 0 : static void AddEntry (unsigned int tok, NameKey_Name name)
381 : : {
382 : 0 : if (ctorGlobals != NULL)
383 : : {
384 : 0 : Lists_IncludeItemIntoList (ctorGlobals, name);
385 : : }
386 : 0 : Lists_IncludeItemIntoList (uselistModules, LookupModuleSym (tok, name));
387 : 0 : }
388 : :
389 : :
390 : : /*
391 : : ReadModules - populate ctorGlobals with the modules specified by -fuse-list=filename.
392 : : */
393 : :
394 : 0 : static void ReadModules (unsigned int tok, DynamicStrings_String filename)
395 : : {
396 : 0 : FIO_File f;
397 : 0 : DynamicStrings_String s;
398 : :
399 : 0 : Lists_InitList (&ctorGlobals);
400 : 0 : Lists_InitList (&uselistModules);
401 : 0 : f = SFIO_OpenToRead (filename);
402 : 0 : while (! (FIO_EOF (f)))
403 : : {
404 : 0 : s = SFIO_ReadS (f);
405 : 0 : s = DynamicStrings_RemoveComment (DynamicStrings_RemoveWhitePrefix (s), Comment);
406 : 0 : if ((! (DynamicStrings_Equal (DynamicStrings_Mark (DynamicStrings_InitStringChar (Comment)), DynamicStrings_Mark (DynamicStrings_Slice (s, 0, static_cast<int> ((DynamicStrings_Length (DynamicStrings_Mark (DynamicStrings_InitStringChar (Comment))))-1)))))) && (! (DynamicStrings_EqualArray (s, (const char *) "", 0))))
407 : : {
408 : 0 : AddEntry (tok, NameKey_makekey (DynamicStrings_string (s)));
409 : : }
410 : 0 : s = DynamicStrings_KillString (s);
411 : : }
412 : 0 : FIO_Close (f);
413 : 0 : }
414 : :
415 : :
416 : : /*
417 : : AddModuleToCtor - adds moduleSym to the uselistModules and
418 : : sets all modules ctors as extern.
419 : : */
420 : :
421 : 63568 : static void AddModuleToCtor (unsigned int moduleSym)
422 : : {
423 : 63568 : if ((SymbolTable_IsModule (moduleSym)) || (! (SymbolTable_IsDefinitionForC (moduleSym))))
424 : : {
425 : 59648 : if ((moduleSym != (SymbolTable_GetMainModule ())) && (! (SymbolTable_IsModuleBuiltin (moduleSym))))
426 : : {
427 : 54868 : SymbolTable_PutModuleCtorExtern (ctorTok, moduleSym, ! M2Options_WholeProgram);
428 : 54868 : Lists_IncludeItemIntoList (uselistModules, moduleSym);
429 : : }
430 : : }
431 : 63568 : }
432 : :
433 : :
434 : : /*
435 : : WriteList - writes the list to GetGenModuleFilename
436 : : providing the filename is not NIL and not '-'.
437 : : */
438 : :
439 : 2390 : static void WriteList (unsigned int tok, Lists_List list)
440 : : {
441 : 2390 : FIO_File fo;
442 : 2390 : NameKey_Name name;
443 : 2390 : unsigned int moduleSym;
444 : 2390 : unsigned int i;
445 : 2390 : unsigned int n;
446 : 2390 : DynamicStrings_String s;
447 : :
448 : 2390 : if (((M2Options_GetGenModuleFilename ()) != NULL) && (! (DynamicStrings_EqualArray (M2Options_GetGenModuleFilename (), (const char *) "-", 1))))
449 : : {
450 : 0 : fo = SFIO_OpenToWrite (M2Options_GetGenModuleFilename ());
451 : 0 : if (FIO_IsNoError (fo))
452 : : {
453 : 0 : i = 1;
454 : 0 : n = Lists_NoOfItemsInList (list);
455 : 0 : while (i <= n)
456 : : {
457 : 0 : moduleSym = static_cast<unsigned int> (Lists_GetItemFromList (list, i));
458 : 0 : name = SymbolTable_GetSymName (moduleSym);
459 : 0 : s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (name));
460 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "\\n", 2)));
461 : 0 : s = FormatStrings_HandleEscape (s);
462 : 0 : s = SFIO_WriteS (fo, s);
463 : 0 : s = DynamicStrings_KillString (s);
464 : 0 : i += 1;
465 : : }
466 : 0 : FIO_Close (fo);
467 : : }
468 : : else
469 : : {
470 : 0 : s = DynamicStrings_InitString ((const char *) "unable to create file containing ctor module list: ", 51);
471 : 0 : s = DynamicStrings_ConCat (s, M2Options_GetGenModuleFilename ());
472 : 0 : M2MetaError_MetaErrorStringT0 (tok, s);
473 : : }
474 : : }
475 : 2390 : }
476 : :
477 : :
478 : : /*
479 : : CreateCtorListFromImports - if GenModuleList then populate
480 : : the ctor list from all modules which are
481 : : not FOR 'C'.
482 : : */
483 : :
484 : 16650 : static bool CreateCtorListFromImports (unsigned int tok)
485 : : {
486 : 16650 : Lists_List newlist;
487 : 16650 : unsigned int i;
488 : 16650 : unsigned int n;
489 : :
490 : 16650 : if (M2Options_GenModuleList)
491 : : {
492 : 2390 : Lists_InitList (&uselistModules);
493 : 2390 : ctorTok = tok;
494 : 2390 : SymbolTable_ForeachModuleDo ((SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) AddModuleToCtor});
495 : 2390 : newlist = TopologicallySortList (uselistModules, SymbolTable_GetMainModule ());
496 : 2390 : Lists_KillList (&uselistModules);
497 : 2390 : uselistModules = newlist;
498 : : /* Now create the ctorGlobals using uselistModules and retain the same order. */
499 : 2390 : Lists_InitList (&ctorGlobals);
500 : 2390 : i = 1;
501 : 2390 : n = Lists_NoOfItemsInList (uselistModules);
502 : 28140 : while (i <= n)
503 : : {
504 : 23360 : Lists_IncludeItemIntoList (ctorGlobals, SymbolTable_GetSymName (Lists_GetItemFromList (uselistModules, i)));
505 : 23360 : i += 1;
506 : : }
507 : 2390 : WriteList (tok, uselistModules);
508 : 2390 : return true;
509 : : }
510 : : return false;
511 : : /* static analysis guarentees a RETURN statement will be used before here. */
512 : : __builtin_unreachable ();
513 : : }
514 : :
515 : :
516 : : /*
517 : : CreateCtorList - uses GetUselistFilename and then reads the list of modules.
518 : : */
519 : :
520 : 16650 : static bool CreateCtorList (unsigned int tok)
521 : : {
522 : 16650 : DynamicStrings_String filename;
523 : :
524 : 16650 : if (M2Options_GetUselist ())
525 : : {
526 : 0 : filename = M2Options_GetUselistFilename ();
527 : 0 : if (filename != NULL)
528 : : {
529 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
530 : 0 : if (SFIO_Exists (filename))
531 : : {
532 : 0 : ReadModules (tok, filename);
533 : 0 : return true;
534 : : }
535 : : else
536 : : {
537 : 0 : if (! (DynamicStrings_EqualArray (filename, (const char *) "-", 1)))
538 : : {
539 : 0 : M2MetaError_MetaErrorT0 (tok, (const char *) "{%E}the filename specified by the -fuse-list= option does not exist", 67);
540 : : }
541 : : }
542 : : }
543 : 0 : return false;
544 : : }
545 : : else
546 : : {
547 : 16650 : return CreateCtorListFromImports (tok);
548 : : }
549 : : /* static analysis guarentees a RETURN statement will be used before here. */
550 : : __builtin_unreachable ();
551 : : }
552 : :
553 : :
554 : : /*
555 : : DeclareModuleExtern - declare the extern _M2_modulename_ctor, _M2_modulename_init,
556 : : _M2_modulename_fini, _M2_modulename_dep for each external module.
557 : : */
558 : :
559 : 2390 : static void DeclareModuleExtern (unsigned int tokenno)
560 : : {
561 : 2390 : NameKey_Name n1;
562 : 2390 : unsigned int init;
563 : 2390 : unsigned int fini;
564 : 2390 : unsigned int dep;
565 : 2390 : unsigned int ctor;
566 : 2390 : unsigned int module;
567 : 2390 : unsigned int n;
568 : 2390 : unsigned int i;
569 : :
570 : 2390 : Lists_InitList (&ctorModules);
571 : 2390 : i = 1;
572 : 2390 : n = Lists_NoOfItemsInList (uselistModules);
573 : 28140 : while (i <= n)
574 : : {
575 : 23360 : module = static_cast<unsigned int> (Lists_GetItemFromList (uselistModules, i));
576 : 23360 : if (module != (SymbolTable_GetMainModule ()))
577 : : {
578 : 20970 : SymbolTable_PutModuleCtorExtern (tokenno, module, ! M2Options_WholeProgram);
579 : : }
580 : 23360 : SymbolTable_GetModuleCtors (module, &ctor, &init, &fini, &dep);
581 : 23360 : Lists_IncludeItemIntoList (ctorModules, ctor);
582 : 23360 : if (Debugging)
583 : : {
584 : : n1 = SymbolTable_GetSymName (module);
585 : : M2Printf_printf1 ((const char *) "%a_ctor added to ctorModules\\n", 30, (const unsigned char *) &n1, (sizeof (n1)-1));
586 : : }
587 : 23360 : i += 1;
588 : : }
589 : 2390 : }
590 : :
591 : :
592 : : /*
593 : : DeclareScaffoldFunctions - declare main, _M2_init,_M2_finish
594 : : and _M2_link to the modula-2
595 : : front end.
596 : : */
597 : :
598 : 16650 : static void DeclareScaffoldFunctions (unsigned int tokenno)
599 : : {
600 : 16650 : if (CreateCtorList (tokenno))
601 : : {
602 : 2390 : DeclareCtorGlobal (tokenno);
603 : 2390 : DeclareModuleExtern (tokenno);
604 : 2390 : M2Scaffold_linkFunction = SymbolTable_MakeProcedure (tokenno, NameKey_MakeKey ((const char *) "_M2_link", 8));
605 : 2390 : SymbolTable_PutMonoName (M2Scaffold_linkFunction, true);
606 : : }
607 : 14260 : else if (M2Options_ScaffoldDynamic && ! M2Options_cflag)
608 : : {
609 : : /* avoid dangling else. */
610 : 0 : M2MetaError_MetaErrorT0 (tokenno, (const char *) "{%O}dynamic linking enabled but no module ctor list has been created, hint use -fuse-list=filename or -fgen-module-list=-", 121);
611 : : }
612 : 16650 : M2Scaffold_initFunction = SymbolTable_MakeProcedure (tokenno, NameKey_MakeKey ((const char *) "_M2_init", 8));
613 : 16650 : SymbolTable_PutMonoName (M2Scaffold_initFunction, true);
614 : 16650 : M2Scaffold_finiFunction = SymbolTable_MakeProcedure (tokenno, NameKey_MakeKey ((const char *) "_M2_fini", 8));
615 : 16650 : SymbolTable_PutMonoName (M2Scaffold_finiFunction, true);
616 : 16650 : if (M2Options_SharedFlag)
617 : : {
618 : 0 : SymbolTable_PutCtor (M2Scaffold_initFunction, true);
619 : 0 : SymbolTable_PutCtor (M2Scaffold_finiFunction, true);
620 : : }
621 : : else
622 : : {
623 : 16650 : M2Scaffold_DeclareArgEnvParams (tokenno, M2Scaffold_initFunction);
624 : 16650 : M2Scaffold_DeclareArgEnvParams (tokenno, M2Scaffold_finiFunction);
625 : 16650 : M2Scaffold_mainFunction = SymbolTable_MakeProcedure (tokenno, NameKey_MakeKey ((const char *) "main", 4));
626 : 16650 : SymbolTable_PutMonoName (M2Scaffold_mainFunction, true);
627 : 16650 : SymbolTable_StartScope (M2Scaffold_mainFunction);
628 : 16650 : SymbolTable_PutFunction (M2Scaffold_mainFunction, M2Base_Integer);
629 : 16650 : M2Scaffold_DeclareArgEnvParams (tokenno, M2Scaffold_mainFunction);
630 : 16650 : SymbolTable_PutPublic (M2Scaffold_mainFunction, true);
631 : 16650 : SymbolTable_EndScope ();
632 : : }
633 : 16650 : }
634 : :
635 : :
636 : : /*
637 : : DeclareScaffold - declare scaffold related entities.
638 : : */
639 : :
640 : 17034 : extern "C" void M2Scaffold_DeclareScaffold (unsigned int tokno)
641 : : {
642 : 17034 : if (! initialized)
643 : : {
644 : 16650 : initialized = true;
645 : 16650 : DeclareScaffoldFunctions (tokno);
646 : : }
647 : 17034 : }
648 : :
649 : :
650 : : /*
651 : : DeclareArgEnvParams - declares (int argc, void *argv, void *envp)
652 : : */
653 : :
654 : 197982 : extern "C" void M2Scaffold_DeclareArgEnvParams (unsigned int tokno, unsigned int proc)
655 : : {
656 : 197982 : Assertion_Assert (SymbolTable_IsProcedure (proc));
657 : 197982 : SymbolTable_StartScope (proc);
658 : 197982 : Assertion_Assert (SymbolTable_PutParam (tokno, proc, 1, NameKey_MakeKey ((const char *) "argc", 4), M2Base_Integer, false));
659 : 197982 : Assertion_Assert (SymbolTable_PutParam (tokno, proc, 2, NameKey_MakeKey ((const char *) "argv", 4), M2System_Address, false));
660 : 197982 : Assertion_Assert (SymbolTable_PutParam (tokno, proc, 3, NameKey_MakeKey ((const char *) "envp", 4), M2System_Address, false));
661 : 197982 : SymbolTable_EndScope ();
662 : 197982 : }
663 : :
664 : :
665 : : /*
666 : : PopulateCtorArray - assign each element of the ctorArray to the external module ctor.
667 : : This is only used to force the linker to pull in the ctors from
668 : : a library.
669 : : */
670 : :
671 : 2378 : extern "C" void M2Scaffold_PopulateCtorArray (unsigned int tok)
672 : : {
673 : 2378 : unsigned int i;
674 : 2378 : unsigned int n;
675 : :
676 : 2378 : n = Lists_NoOfItemsInList (ctorModules);
677 : 2378 : i = 1;
678 : 28104 : while (i <= n)
679 : : {
680 : 23348 : M2Quads_PushTFtok (M2Scaffold_ctorArray, ctorArrayType, tok);
681 : 23348 : M2Quads_PushTtok (SymbolTable_MakeConstant (tok, i), tok);
682 : 23348 : M2Quads_BuildDesignatorArray ();
683 : 23348 : M2Quads_PushTtok (Lists_GetItemFromList (ctorModules, i), tok);
684 : 23348 : M2Quads_BuildAssignment (tok);
685 : 23348 : i += 1;
686 : : }
687 : 2378 : }
688 : :
689 : :
690 : : /*
691 : : ForeachModuleCallInit - is only called when -fscaffold-static is enabled.
692 : : precondition: the module list will be ordered.
693 : : postcondition: foreach module in the application universe
694 : : call _M2_module_init (argc, argv, envp);
695 : : */
696 : :
697 : 0 : extern "C" void M2Scaffold_ForeachModuleCallInit (unsigned int tok, unsigned int argc, unsigned int argv, unsigned int envp)
698 : : {
699 : 0 : unsigned int module;
700 : 0 : unsigned int i;
701 : 0 : unsigned int n;
702 : 0 : unsigned int ctor;
703 : 0 : unsigned int init;
704 : 0 : unsigned int fini;
705 : 0 : unsigned int dep;
706 : :
707 : 0 : i = 1;
708 : 0 : n = Lists_NoOfItemsInList (uselistModules);
709 : 0 : while (i <= n)
710 : : {
711 : 0 : module = static_cast<unsigned int> (Lists_GetItemFromList (uselistModules, i));
712 : 0 : if (module != SymbolTable_NulSym)
713 : : {
714 : 0 : SymbolTable_GetModuleCtors (module, &ctor, &init, &fini, &dep);
715 : 0 : if (init != SymbolTable_NulSym)
716 : : {
717 : 0 : M2Quads_PushTtok (init, tok);
718 : 0 : M2Quads_PushTtok (argc, tok);
719 : 0 : M2Quads_PushTtok (argv, tok);
720 : 0 : M2Quads_PushTtok (envp, tok);
721 : 0 : M2Quads_PushT (static_cast<unsigned int> (3));
722 : 0 : M2Quads_BuildProcedureCall (tok);
723 : : }
724 : : }
725 : 0 : i += 1;
726 : : }
727 : 0 : }
728 : :
729 : :
730 : : /*
731 : : ForeachModuleCallFinish - precondition: the module list will be ordered.
732 : : postcondition: foreach module in the application universe
733 : : call _M2_module_fini (argc, argv, envp);
734 : : */
735 : :
736 : 0 : extern "C" void M2Scaffold_ForeachModuleCallFinish (unsigned int tok, unsigned int argc, unsigned int argv, unsigned int envp)
737 : : {
738 : 0 : unsigned int module;
739 : 0 : unsigned int i;
740 : 0 : unsigned int ctor;
741 : 0 : unsigned int init;
742 : 0 : unsigned int fini;
743 : 0 : unsigned int dep;
744 : :
745 : 0 : i = Lists_NoOfItemsInList (uselistModules);
746 : 0 : while (i >= 1)
747 : : {
748 : 0 : module = static_cast<unsigned int> (Lists_GetItemFromList (uselistModules, i));
749 : 0 : if (module != SymbolTable_NulSym)
750 : : {
751 : 0 : SymbolTable_GetModuleCtors (module, &ctor, &init, &fini, &dep);
752 : 0 : if (fini != SymbolTable_NulSym)
753 : : {
754 : 0 : M2Quads_PushTtok (fini, tok);
755 : 0 : M2Quads_PushTtok (argc, tok);
756 : 0 : M2Quads_PushTtok (argv, tok);
757 : 0 : M2Quads_PushTtok (envp, tok);
758 : 0 : M2Quads_PushT (static_cast<unsigned int> (3));
759 : 0 : M2Quads_BuildProcedureCall (tok);
760 : : }
761 : : }
762 : 0 : i -= 1;
763 : : }
764 : 0 : }
765 : :
766 : 0 : extern "C" void _M2_M2Scaffold_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
767 : : {
768 : 0 : initialized = false;
769 : 0 : M2Scaffold_finiFunction = SymbolTable_NulSym;
770 : 0 : M2Scaffold_initFunction = SymbolTable_NulSym;
771 : 0 : M2Scaffold_mainFunction = SymbolTable_NulSym;
772 : 0 : M2Scaffold_linkFunction = SymbolTable_NulSym;
773 : 0 : M2Scaffold_ctorArray = SymbolTable_NulSym;
774 : 0 : ctorGlobals = static_cast<Lists_List> (NULL);
775 : 0 : ctorModules = static_cast<Lists_List> (NULL);
776 : 0 : uselistModules = static_cast<Lists_List> (NULL);
777 : 0 : }
778 : :
779 : 0 : extern "C" void _M2_M2Scaffold_fini (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
780 : : {
781 : 0 : }
|