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