From 60d5705cc287dcb8cd7d0c84fecb1055d88ad6e9 Mon Sep 17 00:00:00 2001 From: Jean Privat Date: Fri, 25 Nov 2011 10:07:49 -0500 Subject: [PATCH] icode: ITypeCheck requires a receiver 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 --- src/analysis/icode_dump.nit | 2 +- src/compiling/compiling_icode.nit | 6 +++--- src/icode/icode_base.nit | 9 +++++---- src/icode/icode_builder.nit | 2 +- src/icode/icode_tools.nit | 2 +- src/syntax/icode_generation.nit | 7 ++++++- 6 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/analysis/icode_dump.nit b/src/analysis/icode_dump.nit index f72f74c..926a6fc 100644 --- a/src/analysis/icode_dump.nit +++ b/src/analysis/icode_dump.nit @@ -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 diff --git a/src/compiling/compiling_icode.nit b/src/compiling/compiling_icode.nit index 00e87c4..4467942 100644 --- a/src/compiling/compiling_icode.nit +++ b/src/compiling/compiling_icode.nit @@ -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 diff --git a/src/icode/icode_base.nit b/src/icode/icode_base.nit index 09c966b..b2c67f0 100644 --- a/src/icode/icode_base.nit +++ b/src/icode/icode_base.nit @@ -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 diff --git a/src/icode/icode_builder.nit b/src/icode/icode_builder.nit index d5c9753..c50ab6a 100644 --- a/src/icode/icode_builder.nit +++ b/src/icode/icode_builder.nit @@ -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 diff --git a/src/icode/icode_tools.nit b/src/icode/icode_tools.nit index cfe1992..6316748 100644 --- a/src/icode/icode_tools.nit +++ b/src/icode/icode_tools.nit @@ -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 diff --git a/src/syntax/icode_generation.nit b/src/syntax/icode_generation.nit index d78829f..260d1e5 100644 --- a/src/syntax/icode_generation.nit +++ b/src/syntax/icode_generation.nit @@ -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 -- 1.7.9.5