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-2026 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 2684 : static unsigned int DeclareCtorArrayType (unsigned int tokenno, unsigned int high)
215 : {
216 2684 : unsigned int subscript;
217 2684 : unsigned int subrange;
218 :
219 : /* ctorArrayType = ARRAY [0..n] OF PROC ; */
220 2684 : ctorArrayType = SymbolTable_MakeArray (tokenno, NameKey_MakeKey ((const char *) "ctorGlobalType", 14));
221 2684 : SymbolTable_PutArray (ctorArrayType, M2Base_Proc);
222 2684 : subrange = SymbolTable_MakeSubrange (tokenno, NameKey_NulName);
223 2684 : SymbolTable_PutSubrange (subrange, SymbolTable_MakeConstant (tokenno, 0), SymbolTable_MakeConstant (tokenno, high), M2Base_Cardinal);
224 2684 : subscript = SymbolTable_MakeSubscript ();
225 2684 : SymbolTable_PutSubscript (subscript, subrange);
226 2684 : SymbolTable_PutArraySubscript (ctorArrayType, subscript);
227 2684 : 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 2684 : static void DeclareCtorGlobal (unsigned int tokenno)
238 : {
239 2684 : unsigned int n;
240 :
241 2684 : n = Lists_NoOfItemsInList (ctorGlobals);
242 2684 : ctorArrayType = DeclareCtorArrayType (tokenno, n);
243 2684 : M2Scaffold_ctorArray = SymbolTable_MakeVar (tokenno, NameKey_MakeKey ((const char *) "_M2_ctorArray", 13));
244 2684 : SymbolTable_PutVar (M2Scaffold_ctorArray, ctorArrayType);
245 2684 : }
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 323312 : static void addDependentStatement (M2Graph_Graph graph, unsigned int moduleSym, Lists_List list)
290 : {
291 323312 : NameKey_Name n1;
292 323312 : NameKey_Name n2;
293 323312 : unsigned int import;
294 323312 : unsigned int depmod;
295 323312 : unsigned int i;
296 323312 : unsigned int n;
297 :
298 323312 : n = Lists_NoOfItemsInList (list);
299 323312 : i = 1;
300 981334 : while (i <= n)
301 : {
302 334710 : import = static_cast<unsigned int> (Lists_GetItemFromList (list, i));
303 334710 : Assertion_Assert (SymbolTable_IsImport (import));
304 334710 : depmod = SymbolTable_GetImportModule (import);
305 334710 : M2Graph_AddDependent (graph, moduleSym, depmod);
306 334710 : 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 334710 : i += 1;
313 : }
314 323312 : }
315 :
316 :
317 : /*
318 : addDependentImport - adds dependent imports of moduleSym into the graph.
319 : */
320 :
321 174636 : static void addDependentImport (M2Graph_Graph graph, unsigned int moduleSym, Lists_List importList)
322 : {
323 174636 : unsigned int stmt;
324 174636 : unsigned int i;
325 174636 : unsigned int n;
326 :
327 174636 : n = Lists_NoOfItemsInList (importList);
328 174636 : i = 1;
329 672584 : while (i <= n)
330 : {
331 323312 : stmt = static_cast<unsigned int> (Lists_GetItemFromList (importList, i));
332 323312 : Assertion_Assert (SymbolTable_IsImportStatement (stmt));
333 323312 : addDependentStatement (graph, moduleSym, SymbolTable_GetImportStatementList (stmt));
334 323312 : i += 1;
335 : }
336 174636 : }
337 :
338 :
339 : /*
340 : TopologicallySortList - topologically sort the list based on import graph.
341 : A new list is returned.
342 : */
343 :
344 2684 : static Lists_List TopologicallySortList (Lists_List list, unsigned int topModule)
345 : {
346 2684 : M2Graph_Graph graph;
347 2684 : unsigned int i;
348 2684 : unsigned int n;
349 2684 : unsigned int moduleSym;
350 :
351 2684 : graph = M2Graph_InitGraph ();
352 2684 : n = Lists_NoOfItemsInList (list);
353 2684 : i = 1;
354 90002 : while (i <= n)
355 : {
356 84634 : moduleSym = static_cast<unsigned int> (Lists_GetItemFromList (uselistModules, i));
357 84634 : addDependentImport (graph, moduleSym, SymbolTable_GetModuleDefImportStatementList (moduleSym));
358 84634 : addDependentImport (graph, moduleSym, SymbolTable_GetModuleModImportStatementList (moduleSym));
359 84634 : i += 1;
360 : }
361 : /* Ensure that topModule is also in the graph. */
362 2684 : if (! (Lists_IsItemInList (list, topModule)))
363 : {
364 2684 : addDependentImport (graph, topModule, SymbolTable_GetModuleDefImportStatementList (topModule));
365 2684 : addDependentImport (graph, topModule, SymbolTable_GetModuleModImportStatementList (topModule));
366 : }
367 2684 : 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 99290 : static void AddModuleToCtor (unsigned int moduleSym)
419 : {
420 99290 : if ((SymbolTable_IsModule (moduleSym)) || (! (SymbolTable_IsDefinitionForC (moduleSym))))
421 : {
422 90002 : if ((moduleSym != (SymbolTable_GetMainModule ())) && (! (SymbolTable_IsModuleBuiltin (moduleSym))))
423 : {
424 84634 : SymbolTable_PutModuleCtorExtern (ctorTok, moduleSym, ! M2Options_WholeProgram);
425 84634 : Lists_IncludeItemIntoList (uselistModules, moduleSym);
426 : }
427 : }
428 99290 : }
429 :
430 :
431 : /*
432 : WriteList - writes the list to GetGenModuleFilename
433 : providing the filename is not NIL and not '-'.
434 : */
435 :
436 2684 : static void WriteList (unsigned int tok, Lists_List list)
437 : {
438 2684 : FIO_File fo;
439 2684 : NameKey_Name name;
440 2684 : unsigned int moduleSym;
441 2684 : unsigned int i;
442 2684 : unsigned int n;
443 2684 : DynamicStrings_String s;
444 :
445 2684 : 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 2684 : }
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 14577 : static bool CreateCtorListFromImports (unsigned int tok)
482 : {
483 14577 : Lists_List newlist;
484 14577 : unsigned int i;
485 14577 : unsigned int n;
486 :
487 14577 : if (M2Options_GenModuleList)
488 : {
489 2684 : Lists_InitList (&uselistModules);
490 2684 : ctorTok = tok;
491 2684 : SymbolTable_ForeachModuleDo ((SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) AddModuleToCtor});
492 2684 : newlist = TopologicallySortList (uselistModules, SymbolTable_GetMainModule ());
493 2684 : Lists_KillList (&uselistModules);
494 2684 : uselistModules = newlist;
495 : /* Now create the ctorGlobals using uselistModules and retain the same order. */
496 2684 : Lists_InitList (&ctorGlobals);
497 2684 : i = 1;
498 2684 : n = Lists_NoOfItemsInList (uselistModules);
499 36828 : while (i <= n)
500 : {
501 31460 : Lists_IncludeItemIntoList (ctorGlobals, SymbolTable_GetSymName (Lists_GetItemFromList (uselistModules, i)));
502 31460 : i += 1;
503 : }
504 2684 : WriteList (tok, uselistModules);
505 2684 : 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 14577 : static bool CreateCtorList (unsigned int tok)
518 : {
519 14577 : DynamicStrings_String filename;
520 :
521 14577 : 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 14577 : 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 2684 : static void DeclareModuleExtern (unsigned int tokenno)
557 : {
558 2684 : NameKey_Name n1;
559 2684 : unsigned int init;
560 2684 : unsigned int fini;
561 2684 : unsigned int dep;
562 2684 : unsigned int ctor;
563 2684 : unsigned int module;
564 2684 : unsigned int n;
565 2684 : unsigned int i;
566 :
567 2684 : Lists_InitList (&ctorModules);
568 2684 : i = 1;
569 2684 : n = Lists_NoOfItemsInList (uselistModules);
570 36828 : while (i <= n)
571 : {
572 31460 : module = static_cast<unsigned int> (Lists_GetItemFromList (uselistModules, i));
573 31460 : if (module != (SymbolTable_GetMainModule ()))
574 : {
575 28776 : SymbolTable_PutModuleCtorExtern (tokenno, module, ! M2Options_WholeProgram);
576 : }
577 31460 : SymbolTable_GetModuleCtors (module, &ctor, &init, &fini, &dep);
578 31460 : Lists_IncludeItemIntoList (ctorModules, ctor);
579 31460 : 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 31460 : i += 1;
585 : }
586 2684 : }
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 14577 : static void DeclareScaffoldFunctions (unsigned int tokenno)
596 : {
597 14577 : if (CreateCtorList (tokenno))
598 : {
599 2684 : DeclareCtorGlobal (tokenno);
600 2684 : DeclareModuleExtern (tokenno);
601 2684 : M2Scaffold_linkFunction = SymbolTable_MakeProcedure (tokenno, NameKey_MakeKey ((const char *) "_M2_link", 8));
602 2684 : SymbolTable_PutMonoName (M2Scaffold_linkFunction, true);
603 2684 : SymbolTable_PutProcedureDefined (M2Scaffold_linkFunction, SymbolTable_ProperProcedure);
604 : }
605 11893 : else if (M2Options_ScaffoldDynamic && ! M2Options_cflag)
606 : {
607 : /* avoid dangling else. */
608 15 : M2MetaError_MetaErrorT0 (tokenno, (const char *) "{%O}dynamic module registration enabled but no module ctor list has been created, hint use -fuse-list=filename or -fgen-module-list=-", 133);
609 : }
610 14577 : M2Scaffold_initFunction = SymbolTable_MakeProcedure (tokenno, NameKey_MakeKey ((const char *) "_M2_init", 8));
611 14577 : SymbolTable_PutMonoName (M2Scaffold_initFunction, true);
612 14577 : SymbolTable_PutProcedureDefined (M2Scaffold_initFunction, SymbolTable_ProperProcedure);
613 14577 : M2Scaffold_finiFunction = SymbolTable_MakeProcedure (tokenno, NameKey_MakeKey ((const char *) "_M2_fini", 8));
614 14577 : SymbolTable_PutMonoName (M2Scaffold_finiFunction, true);
615 14577 : SymbolTable_PutProcedureDefined (M2Scaffold_initFunction, SymbolTable_ProperProcedure);
616 14577 : if (M2Options_SharedFlag)
617 : {
618 0 : SymbolTable_PutCtor (M2Scaffold_initFunction, true);
619 0 : SymbolTable_PutCtor (M2Scaffold_finiFunction, true);
620 : }
621 : else
622 : {
623 14577 : M2Scaffold_DeclareArgEnvParams (tokenno, M2Scaffold_initFunction);
624 14577 : M2Scaffold_DeclareArgEnvParams (tokenno, M2Scaffold_finiFunction);
625 14577 : M2Scaffold_mainFunction = SymbolTable_MakeProcedure (tokenno, NameKey_MakeKey ((const char *) "main", 4));
626 14577 : SymbolTable_PutMonoName (M2Scaffold_mainFunction, true);
627 14577 : SymbolTable_StartScope (M2Scaffold_mainFunction);
628 14577 : SymbolTable_PutFunction (M2LexBuf_BuiltinTokenNo, M2Scaffold_mainFunction, SymbolTable_ProperProcedure, M2Base_Integer);
629 14577 : M2Scaffold_DeclareArgEnvParams (tokenno, M2Scaffold_mainFunction);
630 14577 : SymbolTable_PutPublic (M2Scaffold_mainFunction, true);
631 14577 : SymbolTable_PutProcedureDefined (M2Scaffold_mainFunction, SymbolTable_ProperProcedure);
632 14577 : SymbolTable_EndScope ();
633 : }
634 14577 : }
635 :
636 :
637 : /*
638 : DeclareScaffold - declare scaffold related entities.
639 : */
640 :
641 15105 : extern "C" void M2Scaffold_DeclareScaffold (unsigned int tokno)
642 : {
643 15105 : if (! initialized)
644 : {
645 14577 : initialized = true;
646 14577 : DeclareScaffoldFunctions (tokno);
647 : }
648 15105 : }
649 :
650 :
651 : /*
652 : DeclareArgEnvParams - declares (int argc, void *argv, void *envp)
653 : */
654 :
655 247763 : extern "C" void M2Scaffold_DeclareArgEnvParams (unsigned int tokno, unsigned int proc)
656 : {
657 247763 : Assertion_Assert (SymbolTable_IsProcedure (proc));
658 247763 : SymbolTable_StartScope (proc);
659 247763 : Assertion_Assert (SymbolTable_PutParam (tokno, proc, SymbolTable_ProperProcedure, 1, NameKey_MakeKey ((const char *) "argc", 4), M2Base_Integer, false, tokno));
660 247763 : Assertion_Assert (SymbolTable_PutParam (tokno, proc, SymbolTable_ProperProcedure, 2, NameKey_MakeKey ((const char *) "argv", 4), M2System_Address, false, tokno));
661 247763 : Assertion_Assert (SymbolTable_PutParam (tokno, proc, SymbolTable_ProperProcedure, 3, NameKey_MakeKey ((const char *) "envp", 4), M2System_Address, false, tokno));
662 247763 : SymbolTable_PutProcedureParametersDefined (proc, SymbolTable_ProperProcedure);
663 247763 : SymbolTable_PutProcedureDeclaredTok (proc, SymbolTable_ProperProcedure, tokno);
664 247763 : SymbolTable_EndScope ();
665 247763 : }
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 2672 : extern "C" void M2Scaffold_PopulateCtorArray (unsigned int tok)
675 : {
676 2672 : unsigned int i;
677 2672 : unsigned int n;
678 :
679 2672 : n = Lists_NoOfItemsInList (ctorModules);
680 2672 : i = 1;
681 36792 : while (i <= n)
682 : {
683 31448 : M2Quads_PushTFtok (M2Scaffold_ctorArray, ctorArrayType, tok);
684 31448 : M2Quads_PushTtok (SymbolTable_MakeConstant (tok, i), tok);
685 31448 : M2Quads_BuildDesignatorArray ();
686 31448 : M2Quads_PushTtok (Lists_GetItemFromList (ctorModules, i), tok);
687 31448 : M2Quads_BuildAssignment (tok);
688 31448 : i += 1;
689 : }
690 2672 : }
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 : }
|