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