1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2009 Jean-Sebastien Gelinas <calestar@gmail.com>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 # Common things to represent a Nit program/library
22 private import primitive_info
25 redef class ToolContext
26 readable writable var _global
: Bool = false
27 writable var _use_SFT_optimization
: Bool = true
29 # We can say that we are using SFT optimization *only* when we are
30 # doing global compilation and we enabled the command line option
31 fun use_SFT_optimization
: Bool do return global
and _use_SFT_optimization
34 # Instances of this class represent a program/library that will
35 # be analyzed/compiled by nitc
37 # This is the ToolContext associated with this Program
38 # It contains (amongts other things) the command line options
39 readable var _tc
: ToolContext
41 # This module is the 'main' module, the one where we find the 'main' method
42 readable var _main_module
: MMModule
44 # This method is the entry point of this program
45 # There might be no entry point (if in fact we are compiling a library)
46 readable var _main_method
: nullable MMMethod = null
48 # This is the class that contains the main method.
49 # Would be null if there is no main method
50 readable var _main_class
: nullable MMLocalClass = null
52 # This method will ensure that all the metamodel is computed before we
53 # start using all the classes
54 private fun finish_processing_classes
do
55 var classes
= new Array[MMLocalClass]
56 for c
in main_module
.local_classes
do
57 c
.compute_super_classes
66 fun compute_main_method
do
67 # Check for the 'Sys' class
68 var sysname
= once
"Sys".to_symbol
69 if not main_module
.has_global_class_named
(sysname
) then return
70 var sys
= main_module
.class_by_name
(sysname
)
72 # Check for 'Sys::main' method
73 var entryname
= once
"main".to_symbol
74 if not sys
.has_global_property_by_name
(entryname
) then return
76 _main_method
= sys
.select_method
(entryname
)
80 # Generation of allocation function of this class
81 fun generate_allocation_iroutines
83 for c
in main_module
.local_classes
do
84 if c
.global
.is_abstract
or c
.global
.is_interface
then continue
85 var pi
= c
.primitive_info
88 # Generate INIT_ATTRIBUTES routine
89 var iself
= new IRegister(c
.get_type
)
91 var iroutine
= new IRoutine(iselfa
, null)
92 var icb
= new ICodeBuilder(main_module
, iroutine
)
94 for sc
in c
.che
.linear_extension
.reversed
do
95 for g
in sc
.global_properties
do
96 if g
.local_class
!= sc
then continue
97 if not g
.intro
isa MMAttribute then continue
99 var t
= p
.signature
.return_type
100 if p
isa MMAttribute and t
!= null then
102 if ir
== null then continue
103 # FIXME: Not compatible with sep compilation
104 var e
= icb
.inline_routine
(ir
, iselfa
, null).as(not null)
105 icb
.stmt
(new IAttrWrite(p
, iself
, e
))
110 c
.init_var_iroutine
= iroutine
114 var iself
= new IRegister(c
.get_type
)
116 var iroutine
= new IRoutine(iselfa
, null)
117 var icb
= new ICodeBuilder(main_module
, iroutine
)
118 for g
in c
.global_properties
do
119 if not g
.intro
isa MMAttribute then continue
121 var t
= p
.signature
.return_type
122 if p
isa MMAttribute and t
!= null and not t
.is_nullable
then
123 icb
.add_attr_check
(p
, iself
)
127 c
.checknew_iroutine
= iroutine
130 for g
in c
.global_properties
do
131 # FIXME skip invisible constructors
132 if not g
.is_init_for
(c
) then continue
134 assert p
isa MMMethod
136 var iself
= new IRegister(c
.get_type
)
137 var iparams
= new Array[IRegister]
138 for i
in [0..p
.signature
.arity
[ do iparams
.add
(new IRegister(p
.signature
[i
]))
139 var iroutine
= new IRoutine(iparams
, iself
)
140 iroutine
.location
= p
.iroutine
.location
141 var icb
= new ICodeBuilder(main_module
, iroutine
)
143 var inew
= new IAllocateInstance(c
.get_type
)
147 iargs
.add_all
(iparams
)
149 icb
.stmt
(new IInitAttributes(c
.get_type
, iself
))
150 icb
.stmt
(new IStaticCall(p
, iargs
))
151 icb
.stmt
(new ICheckInstance(c
.get_type
, iself
))
153 c
.new_instance_iroutine
[p
] = iroutine
159 # This function will call the attached block for each IRoutines
161 fun with_each_iroutines
162 !action
(i
: IRoutine, m
: MMModule)
164 for m
in main_module
.mhe
.greaters_and_self
do
165 for c
in m
.local_classes
do
166 var iroutine
: nullable IRoutine = null
168 # Process methods and attributes initialization
169 for p
in c
.local_local_properties
do
170 if p
isa MMAttribute then
171 iroutine
= p
.iroutine
172 else if p
isa MMMethod then
173 iroutine
= p
.iroutine
175 if iroutine
== null then continue
179 # Process class-specific iroutines
180 iroutine
= c
.init_var_iroutine
181 if iroutine
!= null then
184 iroutine
= c
.checknew_iroutine
185 if iroutine
!= null then
188 for i
in c
.new_instance_iroutine
.values
do
195 # This function will call the attached block for each MMMethods
197 fun with_each_methods
200 for m
in main_module
.mhe
.greaters_and_self
do
201 for c
in m
.local_classes
do
202 # Process methods and attributes initialization
203 for p
in c
.local_local_properties
do
204 if p
isa MMMethod then
212 # This function will call the attached block for each live local classes
214 fun with_each_live_local_classes
215 !action
(m
: MMLocalClass)
217 for c
in main_module
.local_classes
do
222 init(m
: MMModule, toolcontext
: ToolContext) do
225 finish_processing_classes
229 redef class MMLocalClass
230 # IRoutine for the initialization of the default attributes (called by IInitAttributes)
231 readable writable var _init_var_iroutine
: nullable IRoutine = null
232 # IRoutine to validate the instance after initialization (called by ICheckInstance)
233 readable writable var _checknew_iroutine
: nullable IRoutine = null
234 # IRoutines to call to create a new valid instance (memory allocated, object initialized and validated)
235 # These iroutines will call: IAllocateInstance, IInitAttributes, some init function and ICheckInstance
236 # These routines will be called by INew
237 readable var _new_instance_iroutine
: HashMap[MMMethod, IRoutine] = new HashMap[MMMethod, IRoutine]