icode: iroutine knows its local registers
[nit.git] / src / icode / icode_builder.nit
index 01cdde9..d1dd617 100644 (file)
@@ -48,7 +48,7 @@ class ICodeBuilder
        # Check that the reciever e is not null (IIs + IAbort)
        fun add_null_reciever_check(e: IRegister)
        do
-               var nul = new_register(module.type_none)
+               var nul = lit_null_reg
                var c = expr(new IIs(e, nul), module.type_bool)
                var iif = new IIf(c)
                stmt(iif)
@@ -94,7 +94,7 @@ class ICodeBuilder
        # Add a localized IAbort
        fun add_abort(s: String...)
        do
-               stmt(new IAbort(s, method, module))
+               stmt(new IAbort(s, module))
        end
 
        # Add an assigment to the iroutine return value
@@ -135,12 +135,12 @@ class ICodeBuilder
                        seq = iif.else_seq
                        # Do the "x != null" part iff x is nullable
                        if args[0].stype.is_nullable then
-                               var nul = new_register(module.type_none)
+                               var nul = lit_null_reg
                                cond = expr(new IIs(args[0], nul), module.type_bool)
                                iif = new IIf(cond)
                                stmt(iif)
                                seq = iif.then_seq
-                               add_assignment(reg, expr(new INative("TAG_Bool(false)", null), module.type_bool))
+                               add_assignment(reg, lit_false_reg)
                                seq = iif.else_seq
                        end
                        # "x.==(y)"
@@ -149,6 +149,7 @@ class ICodeBuilder
                        return reg
                end
 
+               if args.first.stype.is_nullable then add_null_reciever_check(args.first)
                var rtype = prop.signature.return_type
                if rtype != null then
                        return expr(icall, rtype)
@@ -158,10 +159,34 @@ class ICodeBuilder
                end
        end
 
+       # Return a literal "null" value
+       fun lit_null_reg: IRegister
+       do
+               return new_register(module.type_none)
+       end
+
+       # Return a literal "true" value
+       fun lit_true_reg: IRegister
+       do
+               var e = new INative("TAG_Bool(true)", null)
+               e.is_pure = true
+               return expr(e, module.type_bool)
+       end
+
+       # Return a literal "false" value
+       fun lit_false_reg: IRegister
+       do
+               var e = new INative("TAG_Bool(false)", null)
+               e.is_pure = true
+               return expr(e, module.type_bool)
+       end
+
        # Get a new register
        fun new_register(s: MMType): IRegister
        do
-               return new IRegister(s)
+               var r = new IRegister(s)
+               iroutine.registers.add(r)
+               return r
        end
 
        # The module where classes and types are extracted
@@ -173,16 +198,12 @@ class ICodeBuilder
        # The current sequence of icodes
        readable writable var _seq: ISeq
 
-       # The method associated to the iroutine (if any)
-       readable var _method: nullable MMMethod
-
-       init(module: MMModule, r: IRoutine, m: nullable MMMethod)
+       init(module: MMModule, r: IRoutine)
        do
                _module = module
                _current_location = r.location
                _iroutine = r
                _seq = r.body
-               _method = m
        end
 
        # New ICodes are set to this location
@@ -216,16 +237,16 @@ redef class MMSignature
        end
 
        # Create an empty IClosureDef that match the signature
-       fun generate_empty_iclosuredef: IClosureDef
+       fun generate_empty_iclosuredef(icb: ICodeBuilder): IClosureDef
        do
                var args = new Array[IRegister]
                for i in [0..arity[ do
-                       args.add(new IRegister(self[i]))
+                       args.add(icb.new_register(self[i]))
                end
                var res: nullable IRegister = null
                var rtype = return_type
                if rtype != null then
-                       res = new IRegister(rtype)
+                       res = icb.new_register(rtype)
                end
                var iroutine = new IClosureDef(args, res)
                var clos: nullable Array[IClosureDecl] = null