From: Jean Privat Date: Thu, 5 Jan 2012 12:10:21 +0000 (-0500) Subject: Merge branch 'tools' into wip X-Git-Tag: v0.5~35 X-Git-Url: http://nitlanguage.org?hp=c1d2deb08ddfab77b844bf98622318aff292d360 Merge branch 'tools' into wip --- 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_base.nit b/src/compiling/compiling_base.nit index e6f7f9a..a53a4e2 100644 --- a/src/compiling/compiling_base.nit +++ b/src/compiling/compiling_base.nit @@ -246,6 +246,18 @@ redef class MMGlobalProperty do return "ATTR_{intro.cname}" end + + # C symbol refering a virtual type class color + fun vt_class_color: String + do + return "VTCOLOR_{intro.cname}" + end + + # C symbol refering a virtual type class id + fun vt_class_id: String + do + return "VTID_{intro.cname}" + end end redef class MMGlobalClass diff --git a/src/compiling/compiling_global.nit b/src/compiling/compiling_global.nit index df5b326..a79ddeb 100644 --- a/src/compiling/compiling_global.nit +++ b/src/compiling/compiling_global.nit @@ -205,6 +205,39 @@ redef class TableEltSuper end end +redef class TableEltVTClassColor + redef fun compile_macros(v, value) + do + var pg = property.global + v.add_decl("#define {pg.vt_class_color}(recv) (VAL2VFT(recv)[{value}].i)") + end + + redef fun compile_to_c(v, c) + do + var prog = v.program + var p = c[property.global] + var g = p.signature_for(c.get_type).return_type.local_class.global + var col = g.intro.as(MMConcreteClass).class_color_pos + return "{prog.table_information.color(col)} /* {prog.table_information.color(self)}: VT {c}::{p} : color of {g} */" + end +end + +redef class TableEltVTClassId + redef fun compile_macros(v, value) + do + var pg = property.global + v.add_decl("#define {pg.vt_class_id}(recv) (VAL2VFT(recv)[{value}].i)") + end + + redef fun compile_to_c(v, c) + do + var prog = v.program + var p = c[property.global] + var g = p.signature_for(c.get_type).return_type.local_class.global + return "{prog.compiled_classes[g].id} /* {prog.table_information.color(self)}: VT {c}::{p} : id of {g} */" + end +end + redef class TableEltAttr redef fun compile_macros(v, value) do @@ -220,6 +253,7 @@ redef class TableEltAttr end end + redef class AbsTableEltClass # The C macro name refering the value fun symbol: String is abstract diff --git a/src/compiling/compiling_icode.nit b/src/compiling/compiling_icode.nit index 1f71a74..da6e273 100644 --- a/src/compiling/compiling_icode.nit +++ b/src/compiling/compiling_icode.nit @@ -1023,18 +1023,16 @@ redef class ITypeCheck redef fun compile_to_c(v) do if not need_result then return - # 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 @@ -1044,15 +1042,38 @@ redef class ITypeCheck w.add("!=NIT_NULL) && ") end end - w.add("VAL_ISA(") - w.add(recv) - w.add(", ") - w.add(g.color_id) - w.add(", ") - w.add(g.id_id) - w.add(")) /*cast ") - w.add(stype.to_s) - w.add("*/") + # FIXME handle formaltypes + var t = stype + if t isa MMVirtualType then + var slf = v.register(expr1) + var g = t.property.global + w.add("VAL_ISA(") + w.add(recv) + w.add(", ") + w.add(g.vt_class_color) + w.add("(") + w.add(slf) + w.add(")") + w.add(", ") + w.add(g.vt_class_id) + w.add("(") + w.add(slf) + w.add(")") + w.add(")) /*cast ") + w.add(t.to_s) + w.add("*/") + else + var g = t.local_class.global + w.add("VAL_ISA(") + w.add(recv) + w.add(", ") + w.add(g.color_id) + w.add(", ") + w.add(g.id_id) + w.add(")) /*cast ") + w.add(t.to_s) + w.add("*/") + end end end diff --git a/src/compiling/table_computation.nit b/src/compiling/table_computation.nit index b3c909e..fc50b9d 100644 --- a/src/compiling/table_computation.nit +++ b/src/compiling/table_computation.nit @@ -112,6 +112,9 @@ redef class MMConcreteClass ilt.add(new TableEltAttr(p)) else if p isa MMMethod then clt.add(new TableEltMeth(p)) + else if p isa MMTypeProperty then + clt.add(new TableEltVTClassId(p)) + clt.add(new TableEltVTClassColor(p)) end end if p isa MMMethod and p.need_super then @@ -453,6 +456,16 @@ class TableEltMeth super TableEltProp end +# An element that represents a class color value for a virtual type +class TableEltVTClassColor + super TableEltProp +end + +# An element that represents a class id value for a virtual type +class TableEltVTClassId + super TableEltProp +end + # An element that represents a function pointer to the super method of a local method class TableEltSuper super TableEltProp diff --git a/src/icode/icode_base.nit b/src/icode/icode_base.nit index 5ceb1cb..ea13a9f 100644 --- a/src/icode/icode_base.nit +++ b/src/icode/icode_base.nit @@ -459,15 +459,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..7f37b75 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 @@ -244,6 +244,14 @@ redef class MMSignature end iroutine.closure_decls = clos end + # Add automatic test for virtual types + var icb = new ICodeBuilder(recv.mmmodule, iroutine) + for i in [0..arity[ do + var t = self[i] + if t isa MMVirtualType then + icb.add_type_cast(args[i+1], t) + end + end return iroutine end @@ -268,6 +276,7 @@ redef class MMSignature end iroutine.closure_decls = clos end + # TODO: add automatic test for virtual types? return iroutine end end diff --git a/src/icode/icode_tools.nit b/src/icode/icode_tools.nit index 1071959..ff2b2e8 100644 --- a/src/icode/icode_tools.nit +++ b/src/icode/icode_tools.nit @@ -457,7 +457,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 diff --git a/tests/base_virtual_type_check.nit b/tests/base_virtual_type_check.nit new file mode 100644 index 0000000..37a682a --- /dev/null +++ b/tests/base_virtual_type_check.nit @@ -0,0 +1,90 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import kernel +class A + type T: K + type U: T + fun check(o: Object) + do + o.output + '<'.output + 'T'.output + (o isa T).output + o.output + '<'.output + 'U'.output + (o isa U).output + end + fun check2(o: T) + do + o.output + '<'.output + 'T'.output + '\n'.output + end + fun check3(o: U) + do + o.output + '<'.output + 'U'.output + '\n'.output + end +end +class B + super A + redef type T: L +end +class J + redef fun output do 'J'.output +end +class K + super J + redef fun output do 'K'.output +end +class L + super K + redef fun output do 'L'.output +end + +var a = new A +a.check(new J) +a.check(new K) +a.check(new L) +#alt1#a.check2(new J) # Static error +a.check2(new K) +a.check2(new L) +#alt2#a.check3(new J) # Static error +a.check3(new K) +a.check3(new L) +var b = new B +b.check(new J) +b.check(new K) +b.check(new L) +#alt3#b.check2(new J) # Static error +#alt4#b.check2(new K) # Static error +b.check2(new L) +#alt5#b.check3(new J) # Static error +#alt6#b.check3(new K) # Static error +b.check3(new L) +var ab: A = new B +ab.check(new J) +ab.check(new K) +ab.check(new L) +#alt7#ab.check2(new J) # Static error +#alt8#ab.check2(new K) # Dynamic error +ab.check2(new L) +#alt9#ab.check3(new J) # Static error +#alt10#ab.check3(new K) # Dynamic error +ab.check3(new L) diff --git a/tests/sav/base_virtual_type_check.sav b/tests/sav/base_virtual_type_check.sav new file mode 100644 index 0000000..43474d8 --- /dev/null +++ b/tests/sav/base_virtual_type_check.sav @@ -0,0 +1,26 @@ +J