icode: generate null receiver runtime checks
authorJean Privat <jean@pryen.org>
Sun, 26 Jul 2009 03:07:58 +0000 (23:07 -0400)
committerJean Privat <jean@pryen.org>
Mon, 27 Jul 2009 07:36:20 +0000 (03:36 -0400)
Signed-off-by: Jean Privat <jean@pryen.org>

16 files changed:
src/icode/icode_builder.nit
src/syntax/icode_generation.nit
tests/rterror_null_receiver.nit [new file with mode: 0644]
tests/sav/base_primitive_null_alt1.fail [deleted file]
tests/sav/base_primitive_null_alt1.sav [new file with mode: 0644]
tests/sav/base_primitive_null_alt2.fail [deleted file]
tests/sav/base_primitive_null_alt2.sav [new file with mode: 0644]
tests/sav/base_primitive_null_alt3.fail [deleted file]
tests/sav/base_primitive_null_alt3.sav [new file with mode: 0644]
tests/sav/rterror_null_receiver.sav [new file with mode: 0644]
tests/sav/rterror_null_receiver_alt1.sav [new file with mode: 0644]
tests/sav/rterror_null_receiver_alt2.sav [new file with mode: 0644]
tests/sav/rterror_null_receiver_alt3.sav [new file with mode: 0644]
tests/sav/rterror_null_receiver_alt4.sav [new file with mode: 0644]
tests/sav/rterror_null_receiver_alt5.sav [new file with mode: 0644]
tests/sav/rterror_null_receiver_alt6.sav [new file with mode: 0644]

index 01cdde9..aee4d01 100644 (file)
@@ -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)
index 719eba8..4b6db99 100644 (file)
@@ -1149,6 +1149,7 @@ redef class AAttrExpr
        redef fun generate_icode(v)
        do
                var e = v.generate_expr(n_expr)
+               if n_expr.stype.is_nullable then v.add_null_reciever_check(e)
                return v.add_attr_read(prop, e)
        end
 end
@@ -1157,6 +1158,7 @@ redef class AAttrAssignExpr
        redef fun generate_icode(v)
        do
                var e = v.generate_expr(n_expr)
+               if n_expr.stype.is_nullable then v.add_null_reciever_check(e)
                var e2 = v.generate_expr(n_value)
                v.stmt(new IAttrWrite(prop, e, e2))
                return null
@@ -1166,6 +1168,7 @@ redef class AAttrReassignExpr
        redef fun generate_icode(v)
        do
                var e1 = v.generate_expr(n_expr)
+               if n_expr.stype.is_nullable then v.add_null_reciever_check(e1)
                var e2 = v.expr(new IAttrRead(prop, e1), attr_type)
                var e3 = v.generate_expr(n_value)
                var e4 = v.expr(new ICall(assign_method, [e2, e3]), attr_type)
@@ -1178,6 +1181,7 @@ redef class AIssetAttrExpr
        redef fun generate_icode(v)
        do
                var e = v.generate_expr(n_expr)
+               if n_expr.stype.is_nullable then v.add_null_reciever_check(e)
                return v.expr(new IAttrIsset(prop, e), stype)
        end
 end
@@ -1249,6 +1253,7 @@ redef class ASendReassignExpr
        redef fun generate_icode(v)
        do
                var recv = v.generate_expr(n_expr)
+               if n_expr.stype.is_nullable then v.add_null_reciever_check(recv)
                var args = new Array[IRegister]
                args.add(recv)
                generate_icode_for_arguments_in(v, args)
diff --git a/tests/rterror_null_receiver.nit b/tests/rterror_null_receiver.nit
new file mode 100644 (file)
index 0000000..481973b
--- /dev/null
@@ -0,0 +1,31 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2009 Jean Privat <jean@pryen.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
+       readable writable var _foo: Int = 1
+end
+
+var a: nullable A = null
+(a == null).output
+(a != null).output
+#alt1#a.foo.output
+#alt2#a.foo = 1
+#alt3#a.foo += 1
+#alt4#a._foo.output
+#alt5#a._foo = 10
+#alt6#a._foo += 10
diff --git a/tests/sav/base_primitive_null_alt1.fail b/tests/sav/base_primitive_null_alt1.fail
deleted file mode 100644 (file)
index 4fbbe1f..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-I
-true
-true
-true
-true
-0
-B
-true
-true
-true
-true
-C
-true
-true
-true
-true
diff --git a/tests/sav/base_primitive_null_alt1.sav b/tests/sav/base_primitive_null_alt1.sav
new file mode 100644 (file)
index 0000000..b379a8f
--- /dev/null
@@ -0,0 +1,11 @@
+I
+true
+true
+true
+true
+Reciever is null in base_primitive_null_alt1::A::init (alt/base_primitive_null_alt1.nit:34)
+,---- Stack trace -- - -  -
+| base_primitive_null_alt1::A::init (alt/base_primitive_null_alt1.nit:24)
+| new A base_primitive_null_alt1::A::init (alt/base_primitive_null_alt1.nit:24)
+| base_primitive_null_alt1::Sys::(kernel::Sys::main) (alt/base_primitive_null_alt1.nit:56)
+`------------------- - -  -
diff --git a/tests/sav/base_primitive_null_alt2.fail b/tests/sav/base_primitive_null_alt2.fail
deleted file mode 100644 (file)
index c301ecc..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-I
-true
-true
-true
-true
-B
-true
-true
-true
-true
-false
-C
-true
-true
-true
-true
diff --git a/tests/sav/base_primitive_null_alt2.sav b/tests/sav/base_primitive_null_alt2.sav
new file mode 100644 (file)
index 0000000..a53f21f
--- /dev/null
@@ -0,0 +1,16 @@
+I
+true
+true
+true
+true
+B
+true
+true
+true
+true
+Reciever is null in base_primitive_null_alt2::A::init (alt/base_primitive_null_alt2.nit:43)
+,---- Stack trace -- - -  -
+| base_primitive_null_alt2::A::init (alt/base_primitive_null_alt2.nit:24)
+| new A base_primitive_null_alt2::A::init (alt/base_primitive_null_alt2.nit:24)
+| base_primitive_null_alt2::Sys::(kernel::Sys::main) (alt/base_primitive_null_alt2.nit:56)
+`------------------- - -  -
diff --git a/tests/sav/base_primitive_null_alt3.fail b/tests/sav/base_primitive_null_alt3.fail
deleted file mode 100644 (file)
index e3f7561..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-I
-true
-true
-true
-true
-B
-true
-true
-true
-true
-C
-true
-true
-true
-true
-0
diff --git a/tests/sav/base_primitive_null_alt3.sav b/tests/sav/base_primitive_null_alt3.sav
new file mode 100644 (file)
index 0000000..69e4e5a
--- /dev/null
@@ -0,0 +1,21 @@
+I
+true
+true
+true
+true
+B
+true
+true
+true
+true
+C
+true
+true
+true
+true
+Reciever is null in base_primitive_null_alt3::A::init (alt/base_primitive_null_alt3.nit:52)
+,---- Stack trace -- - -  -
+| base_primitive_null_alt3::A::init (alt/base_primitive_null_alt3.nit:24)
+| new A base_primitive_null_alt3::A::init (alt/base_primitive_null_alt3.nit:24)
+| base_primitive_null_alt3::Sys::(kernel::Sys::main) (alt/base_primitive_null_alt3.nit:56)
+`------------------- - -  -
diff --git a/tests/sav/rterror_null_receiver.sav b/tests/sav/rterror_null_receiver.sav
new file mode 100644 (file)
index 0000000..da29283
--- /dev/null
@@ -0,0 +1,2 @@
+true
+false
diff --git a/tests/sav/rterror_null_receiver_alt1.sav b/tests/sav/rterror_null_receiver_alt1.sav
new file mode 100644 (file)
index 0000000..223e009
--- /dev/null
@@ -0,0 +1,6 @@
+true
+false
+Reciever is null in rterror_null_receiver_alt1::Sys::(kernel::Sys::main) (alt/rterror_null_receiver_alt1.nit:26)
+,---- Stack trace -- - -  -
+| rterror_null_receiver_alt1::Sys::(kernel::Sys::main) (alt/rterror_null_receiver_alt1.nit:23)
+`------------------- - -  -
diff --git a/tests/sav/rterror_null_receiver_alt2.sav b/tests/sav/rterror_null_receiver_alt2.sav
new file mode 100644 (file)
index 0000000..2439b2f
--- /dev/null
@@ -0,0 +1,6 @@
+true
+false
+Reciever is null in rterror_null_receiver_alt2::Sys::(kernel::Sys::main) (alt/rterror_null_receiver_alt2.nit:27)
+,---- Stack trace -- - -  -
+| rterror_null_receiver_alt2::Sys::(kernel::Sys::main) (alt/rterror_null_receiver_alt2.nit:23)
+`------------------- - -  -
diff --git a/tests/sav/rterror_null_receiver_alt3.sav b/tests/sav/rterror_null_receiver_alt3.sav
new file mode 100644 (file)
index 0000000..a15e1ce
--- /dev/null
@@ -0,0 +1,6 @@
+true
+false
+Reciever is null in rterror_null_receiver_alt3::Sys::(kernel::Sys::main) (alt/rterror_null_receiver_alt3.nit:28)
+,---- Stack trace -- - -  -
+| rterror_null_receiver_alt3::Sys::(kernel::Sys::main) (alt/rterror_null_receiver_alt3.nit:23)
+`------------------- - -  -
diff --git a/tests/sav/rterror_null_receiver_alt4.sav b/tests/sav/rterror_null_receiver_alt4.sav
new file mode 100644 (file)
index 0000000..8a34da1
--- /dev/null
@@ -0,0 +1,6 @@
+true
+false
+Reciever is null in rterror_null_receiver_alt4::Sys::(kernel::Sys::main) (alt/rterror_null_receiver_alt4.nit:29)
+,---- Stack trace -- - -  -
+| rterror_null_receiver_alt4::Sys::(kernel::Sys::main) (alt/rterror_null_receiver_alt4.nit:23)
+`------------------- - -  -
diff --git a/tests/sav/rterror_null_receiver_alt5.sav b/tests/sav/rterror_null_receiver_alt5.sav
new file mode 100644 (file)
index 0000000..98001f1
--- /dev/null
@@ -0,0 +1,6 @@
+true
+false
+Reciever is null in rterror_null_receiver_alt5::Sys::(kernel::Sys::main) (alt/rterror_null_receiver_alt5.nit:30)
+,---- Stack trace -- - -  -
+| rterror_null_receiver_alt5::Sys::(kernel::Sys::main) (alt/rterror_null_receiver_alt5.nit:23)
+`------------------- - -  -
diff --git a/tests/sav/rterror_null_receiver_alt6.sav b/tests/sav/rterror_null_receiver_alt6.sav
new file mode 100644 (file)
index 0000000..b582b3c
--- /dev/null
@@ -0,0 +1,6 @@
+true
+false
+Reciever is null in rterror_null_receiver_alt6::Sys::(kernel::Sys::main) (alt/rterror_null_receiver_alt6.nit:31)
+,---- Stack trace -- - -  -
+| rterror_null_receiver_alt6::Sys::(kernel::Sys::main) (alt/rterror_null_receiver_alt6.nit:23)
+`------------------- - -  -