X-Git-Url: http://nitlanguage.org diff --git a/src/program.nit b/src/program.nit index 4bb6ea5..728b7ce 100644 --- a/src/program.nit +++ b/src/program.nit @@ -19,13 +19,27 @@ package program import metamodel import icode -import primitive_info +private import primitive_info +import mmloader + +redef class ToolContext + readable writable var _global: Bool = false + writable var _use_SFT_optimization: Bool = true + + # We can say that we are using SFT optimization *only* when we are + # doing global compilation and we enabled the command line option + fun use_SFT_optimization: Bool do return global and _use_SFT_optimization +end # Instances of this class represent a program/library that will # be analyzed/compiled by nitc class Program + # This is the ToolContext associated with this Program + # It contains (amongts other things) the command line options + readable var _tc: ToolContext + # This module is the 'main' module, the one where we find the 'main' method - readable var _module: MMModule + readable var _main_module: MMModule # This method is the entry point of this program # There might be no entry point (if in fact we are compiling a library) @@ -35,11 +49,25 @@ class Program # Would be null if there is no main method readable var _main_class: nullable MMLocalClass = null + # This method will ensure that all the metamodel is computed before we + # start using all the classes + private fun finish_processing_classes do + var classes = new Array[MMLocalClass] + for c in main_module.local_classes do + c.compute_super_classes + classes.add(c) + end + + for c in classes do + c.compute_ancestors + end + end + fun compute_main_method do # Check for the 'Sys' class var sysname = once "Sys".to_symbol - if not module.has_global_class_named(sysname) then return - var sys = module.class_by_name(sysname) + if not main_module.has_global_class_named(sysname) then return + var sys = main_module.class_by_name(sysname) # Check for 'Sys::main' method var entryname = once "main".to_symbol @@ -52,7 +80,8 @@ class Program # Generation of allocation function of this class fun generate_allocation_iroutines do - for c in module.local_classes do + for c in main_module.local_classes do + if c.global.is_abstract or c.global.is_interface then continue var pi = c.primitive_info if pi == null then do @@ -60,17 +89,21 @@ class Program var iself = new IRegister(c.get_type) var iselfa = [iself] var iroutine = new IRoutine(iselfa, null) - var icb = new ICodeBuilder(module, iroutine) - - for g in c.global_properties do - var p = c[g] - var t = p.signature.return_type - if p isa MMAttribute and t != null then - var ir = p.iroutine - if ir == null then continue - # FIXME: Not compatible with sep compilation - var e = icb.inline_routine(ir, iselfa, null).as(not null) - icb.stmt(new IAttrWrite(p, iself, e)) + var icb = new ICodeBuilder(main_module, iroutine) + + for sc in c.che.linear_extension.reversed do + for g in sc.global_properties do + if g.local_class != sc then continue + if not g.intro isa MMAttribute then continue + var p = c[g] + var t = p.signature.return_type + if p isa MMAttribute and t != null then + var ir = p.iroutine + if ir == null then continue + # FIXME: Not compatible with sep compilation + var e = icb.inline_routine(ir, iselfa, null).as(not null) + icb.stmt(new IAttrWrite(p, iself, e)) + end end end @@ -81,8 +114,9 @@ class Program var iself = new IRegister(c.get_type) var iselfa = [iself] var iroutine = new IRoutine(iselfa, null) - var icb = new ICodeBuilder(module, iroutine) + var icb = new ICodeBuilder(main_module, iroutine) for g in c.global_properties do + if not g.intro isa MMAttribute then continue var p = c[g] var t = p.signature.return_type if p isa MMAttribute and t != null and not t.is_nullable then @@ -94,9 +128,9 @@ class Program end for g in c.global_properties do - var p = c[g] # FIXME skip invisible constructors - if not p.global.is_init_for(c) then continue + if not g.is_init_for(c) then continue + var p = c[g] assert p isa MMMethod var iself = new IRegister(c.get_type) @@ -104,7 +138,7 @@ class Program for i in [0..p.signature.arity[ do iparams.add(new IRegister(p.signature[i])) var iroutine = new IRoutine(iparams, iself) iroutine.location = p.iroutine.location - var icb = new ICodeBuilder(module, iroutine) + var icb = new ICodeBuilder(main_module, iroutine) var inew = new IAllocateInstance(c.get_type) inew.result = iself @@ -122,8 +156,73 @@ class Program end end - init(m: MMModule) do - _module = m + # This function will call the attached block for each IRoutines + # in this program + fun with_each_iroutines + !action(i: IRoutine, m: MMModule) + do + for m in main_module.mhe.greaters_and_self do + for c in m.local_classes do + var iroutine: nullable IRoutine = null + + # Process methods and attributes initialization + for p in c.local_local_properties do + if p isa MMAttribute then + iroutine = p.iroutine + else if p isa MMMethod then + iroutine = p.iroutine + end + if iroutine == null then continue + action(iroutine, m) + end + + # Process class-specific iroutines + iroutine = c.init_var_iroutine + if iroutine != null then + action(iroutine, m) + end + iroutine = c.checknew_iroutine + if iroutine != null then + action(iroutine, m) + end + for i in c.new_instance_iroutine.values do + action(i, m) + end + end + end + end + + # This function will call the attached block for each MMMethods + # in this program + fun with_each_methods + !action(m: MMMethod) + do + for m in main_module.mhe.greaters_and_self do + for c in m.local_classes do + # Process methods and attributes initialization + for p in c.local_local_properties do + if p isa MMMethod then + action(p) + end + end + end + end + end + + # This function will call the attached block for each live local classes + # in this program + fun with_each_live_local_classes + !action(m: MMLocalClass) + do + for c in main_module.local_classes do + action(c) + end + end + + init(m: MMModule, toolcontext: ToolContext) do + _main_module = m + _tc = toolcontext + finish_processing_classes end end