icode: ITypeCheck requires a receiver
authorJean Privat <jean@pryen.org>
Fri, 25 Nov 2011 15:07:49 +0000 (10:07 -0500)
committerJean Privat <jean@pryen.org>
Fri, 25 Nov 2011 15:07:49 +0000 (10:07 -0500)
For complex type checks that involve virtual types or generics,
a receiver is required.

For instance, with T a virtual type and x a variable
   x isa T
is in fact
   x isa self.T

This patch transforms the ITypeCheck from a ICode1 to a ICode2,
where expr1 is the receiver of the type and expr2 is the variable to test.

Clients of ITypeCheck are updated without change of behaviour.
Note that, strangely, during the icode_generation, the register that hold
self is lost, a new attribute is therefore added in A2IContext to store it.

Signed-off-by: Jean Privat <jean@pryen.org>

src/analysis/icode_dump.nit
src/compiling/compiling_icode.nit
src/icode/icode_base.nit
src/icode/icode_builder.nit
src/icode/icode_tools.nit
src/syntax/icode_generation.nit

index f72f74c..926a6fc 100644 (file)
@@ -364,7 +364,7 @@ end
 redef class ITypeCheck
        redef fun dump_intern(icd)
        do
-               return "CHECKTYPE {icd.register(expr)} isa {stype}"
+               return "CHECKTYPE {icd.register(expr2)} isa {stype}"
        end
 end
 
index 00e87c4..4467942 100644 (file)
@@ -1019,15 +1019,15 @@ redef class ITypeCheck
                # FIXME handle formaltypes
                v.add_location(location)
                var g = stype.local_class.global
-               var recv = v.register(expr)
+               var recv = v.register(expr2)
                var w = new_result(v)
                w.add("TAG_Bool(")
-               if expr.stype.is_nullable then
+               if expr2.stype.is_nullable then
                        if stype.is_nullable then
                                w.add("(")
                                w.add(recv)
                                w.add("==NIT_NULL) || ")
-                       else if stype.as_nullable == expr.stype then
+                       else if stype.as_nullable == expr2.stype then
                                w.add(recv)
                                w.add("!=NIT_NULL)")
                                return
index 09c966b..b2c67f0 100644 (file)
@@ -456,15 +456,16 @@ class IAttrIsset
 end
 
 # A type check
-# expr is the expression checked
+# expr1 is the type reciever (self)
+# expr2 is the expression checked
 class ITypeCheck
-       super ICode1
+       super ICode2
        # The static type checkes to
        readable var _stype: MMType
 
-       init(e: IRegister, t: MMType)
+       init(e1, e2: IRegister, t: MMType)
        do
-               super(e)
+               super(e1, e2)
                _stype = t
        end
 
index d5c9753..c50ab6a 100644 (file)
@@ -61,7 +61,7 @@ class ICodeBuilder
        # Add a type cast (ITypeCheck + IAbort) in the current icode sequence
        fun add_type_cast(e: IRegister, stype: MMType)
        do
-               var c = expr(new ITypeCheck(e, stype), mmmodule.type_bool)
+               var c = expr(new ITypeCheck(iroutine.params.first, e, stype), mmmodule.type_bool)
                var iif = new IIf(c)
                stmt(iif)
                var old_seq = seq
index cfe1992..6316748 100644 (file)
@@ -456,7 +456,7 @@ end
 redef class ITypeCheck
        redef fun inner_dup_with(d)
        do
-               return new ITypeCheck(d.dup_ireg(expr), stype)
+               return new ITypeCheck(d.dup_ireg(expr1), d.dup_ireg(expr2), stype)
        end
 end
 
index d78829f..260d1e5 100644 (file)
@@ -82,6 +82,9 @@ class A2IContext
        # The method associated to the iroutine (if any)
        readable var _method: nullable MMMethod
 
+       # The register of self (if any)
+       var selfreg: nullable IRegister writable
+
        init(visitor: AbsSyntaxVisitor, r: IRoutine, m: nullable MMMethod)
        do
                super(visitor.mmmodule, r)
@@ -368,6 +371,7 @@ redef class AConcreteMethPropdef
                var params = v.iroutine.params.to_a
                var selfreg = v.variable(self_var)
                v.stmt(new IMove(selfreg, params[0]))
+               v.selfreg = selfreg
                params.shift
 
                var orig_meth: MMLocalProperty = method.global.intro
@@ -383,6 +387,7 @@ redef class AConcreteMethPropdef
                if n_block != null then
                        v.generate_stmt(n_block)
                end
+               v.selfreg = null
        end
 end
 
@@ -812,7 +817,7 @@ redef class AIsaExpr
        redef fun generate_icode(v)
        do
                var e = v.generate_expr(n_expr)
-               return v.expr(new ITypeCheck(e, n_type.stype), stype)
+               return v.expr(new ITypeCheck(v.selfreg.as(not null), e, n_type.stype), stype)
        end
 end