FreeBASIC  0.91.0
fb-main.bas
Go to the documentation of this file.
1 '' prolog and epilog for the implicit main() function
2 ''
3 '' chng: jun/2005 written [v1ctor]
4 ''
5 
6 
7 #include once "fb.bi"
8 #include once "fbint.bi"
9 #include once "ast.bi"
10 #include once "ir.bi"
11 #include once "rtl.bi"
12 #include once "symb.bi"
13 
14 sub hCallMain( )
15  dim as ASTNODE ptr main = any
16 
17  '' main( 0, NULL )
18  main = astNewCALL( env.main.proc )
19  astNewARG( main, astNewCONSTi( 0 ) )
20  astNewARG( main, astNewCONSTi( NULL, typeAddrOf( FB_DATATYPE_VOID ) ) )
21 
22  '' tell the emitter to not allocate a result
23  astSetType( main, FB_DATATYPE_VOID, NULL )
24 
25  astAdd( main )
26 end sub
27 
29  dim as FBSYMBOL ptr proc = any, label = any, param = any
30 
31  proc = symbPreAddProc( NULL )
32 
33  '' instance
34  symbAddProcParam( proc, "__FB_DLLINSTANCE__", typeAddrOf( FB_DATATYPE_VOID ), NULL, _
35  FB_PARAMMODE_BYVAL, 0 )
36 
37  '' reason
38  param = symbAddProcParam( proc, "__FB_DLLREASON__", FB_DATATYPE_UINT, NULL, _
39  FB_PARAMMODE_BYVAL, 0 )
40 
41  '' reserved
42  symbAddProcParam( proc, "__FB_DLLRESERVED__", typeAddrOf( FB_DATATYPE_VOID ), NULL, _
43  FB_PARAMMODE_BYVAL, 0 )
44 
45  '' function DllMain stdcall( byval instance as any ptr, byval reason as uinteger, _
46  '' byval reserved as any ptr ) as integer
47  proc = symbAddProc( proc, NULL, "DllMain", FB_DATATYPE_INTEGER, NULL, _
48  FB_SYMBATTRIB_PUBLIC, env.target.stdcall, FB_SYMBOPT_DECLARING )
49 
50  astProcBegin( proc, FALSE )
51 
52  '' function = TRUE
54  astNewCONSTi( 1, symbGetType( proc ) ) ) )
55 
56  '' if( reason = DLL_PROCESS_ATTACH ) then
57  param = symbGetParamVar( param )
58  label = symbAddLabel( NULL )
59  astAdd( astNewBOP( AST_OP_NE, _
60  astNewVAR( param ), _
61  astNewCONSTi( 1, FB_DATATYPE_UINT ), _
62  label, AST_OPOPT_NONE ) )
63 
64  '' main( ... )
65  hCallMain( )
66 
67  '' end if
68  astAdd( astNewLABEL( label ) )
69 
70  '' end function
71  astProcEnd( FALSE )
72 end sub
73 
75  dim as FBSYMBOL ptr proc = any
76 
77  '' sub ctor cdecl( ) constructor
78  proc = symbAddProc( symbPreAddProc( NULL ), NULL, "__fb_DllMain_ctor", FB_DATATYPE_VOID, NULL, _
79  FB_SYMBATTRIB_PRIVATE, FB_FUNCMODE_CDECL, FB_SYMBOPT_DECLARING )
80  symbAddGlobalCtor( proc )
81  astProcBegin( proc, FALSE )
82 
83  '' main( ... )
84  hCallMain( )
85 
86  '' end sub
87  astProcEnd( FALSE )
88 end sub
89 
90 sub hMainBegin( )
91  dim as FBSYMBOL ptr proc = any
92 
93  proc = symbPreAddProc( NULL )
94 
95  '' byval argc as long
96  symbAddProcParam( proc, "__FB_ARGC__", FB_DATATYPE_LONG, NULL, _
97  FB_PARAMMODE_BYVAL, 0 )
98 
99  '' byval argv as zstring ptr ptr
100  symbAddProcParam( proc, "__FB_ARGV__", typeMultAddrOf( FB_DATATYPE_CHAR, 2 ), NULL, _
101  FB_PARAMMODE_BYVAL, 0 )
102 
103  '' if it's a dll, the main() function should be private
104  var attrib = FB_SYMBATTRIB_PUBLIC
105  var id = fbGetEntryPoint( )
106  if( env.clopt.outtype = FB_OUTTYPE_DYNAMICLIB ) then
107  attrib = FB_SYMBATTRIB_PRIVATE
108  '' Use a random name for the C backend
109  if( env.clopt.backend = FB_BACKEND_GCC ) then
110  id = *symbUniqueId( )
111  end if
112  end if
113 
114  '' function main cdecl( byval argc as long, byval argv as zstring ptr ptr ) as long
115  env.main.proc = symbAddProc( proc, NULL, id, FB_DATATYPE_LONG, NULL, _
116  attrib, FB_FUNCMODE_CDECL, FB_SYMBOPT_DECLARING )
117 
118  '' Must be done before astProcBegin(), so it will add the fb_Init() call, etc.
119  symbSetIsMainProc( env.main.proc )
120 
121  astProcBegin( env.main.proc, TRUE )
122 end sub
123 
125  '' sub modlevel cdecl( ) constructor
126  env.main.proc = symbAddProc( symbPreAddProc( NULL ), "{modlevel}", fbGetModuleEntry( ), FB_DATATYPE_VOID, NULL, _
127  FB_SYMBATTRIB_PRIVATE, FB_FUNCMODE_CDECL, FB_SYMBOPT_DECLARING )
128  symbAddGlobalCtor( env.main.proc )
129  symbSetIsAccessed( env.main.proc )
130  symbSetIsModLevelProc( env.main.proc )
131 
132  astProcBegin( env.main.proc, TRUE )
133 end sub
134 
136  if( env.outf.ismain ) then
137  '' function main( ... )
138  hMainBegin( )
139  else
140  '' sub modlevel( ) constructor
141  hModLevelBegin( )
142  end if
143 
144  '' Generate a DllMain() or global ctor that calls main()/modlevel() in DLLs/shared libs
145  if( env.outf.ismain and (env.clopt.outtype = FB_OUTTYPE_DYNAMICLIB) ) then
146  if( env.clopt.target = FB_COMPTARGET_WIN32 ) then
148  else
150  end if
151  end if
152 end sub
153 
154 sub fbMainEnd( )
155  dim as integer callrtexit = FALSE
156 
157  if( env.outf.ismain ) then
158  '' set default data label (def label isn't global as it could clash with other
159  '' modules, so DataRestore alone can't figure out where to start)
160  if( astGetFirstDataStmtSymbol( ) <> NULL ) then
161  rtlDataRestore( NULL, env.main.initnode )
162  end if
163 
164  callrtexit = (env.clopt.outtype <> FB_OUTTYPE_DYNAMICLIB)
165  end if
166 
167  '' end sub|function (main() or modlevel())
168  astProcEnd( callrtexit )
169 end sub
170