2 # Copyright (C) 2001-2010, Parrot Foundation.
7 use lib qw( . lib ../lib ../../lib );
9 use Parrot::Test tests => 36;
13 t/pmc/object-meths.t - Object Methods
17 % prove t/pmc/object-meths.t
21 Tests PMC object methods.
25 pasm_error_output_like( <<'CODE', <<'OUTPUT', "callmethodcc - unknown method" );
29 print "should never reach here\n"
32 /Method 'nada' not found for invocant of class 'Foo'/
35 pasm_error_output_like( <<'CODE', <<'OUTPUT', "callmethod (STR) - unknown method" );
39 print "should never reach here\n"
42 /Method 'nada' not found for invocant of class 'Foo'/
45 pasm_error_output_like( <<'CODE', <<'OUTPUT', "callmethodcc - unknown method" );
49 print "should never reach here\n"
52 /Method 'nada' not found for invocant of class 'Foo'/
55 pasm_error_output_like( <<'CODE', <<'OUTPUT', "callmethodcc (STR) - unknown method" );
59 print "should never reach here\n"
62 /Method 'nada' not found for invocant of class 'Foo'/
65 pir_output_is( <<'CODE', <<'OUTPUT', "callmethod 1" );
88 pir_output_is( <<'CODE', <<'OUTPUT', "can class" );
93 # Add a method to the class manually
94 $P2.'add_method'("meth", $P3)
96 # Classes only report 'can' for class methods, not instance methods
106 pir_output_is( <<'CODE', <<'OUTPUT', "can object" );
112 # Add a method to the class manually
113 $P2.'add_method'("meth", $P3)
118 can $I0, $P4, "no_such_meth"
128 pir_output_is( <<'CODE', <<'OUTPUT', "constructor" );
137 .sub init :method :vtable
145 pir_output_is( <<'CODE', <<'OUTPUT', "constructor - init attr" );
148 addattribute $P1, ".i"
157 .sub 'init' :vtable :method
159 new $P10, ['Integer']
161 setattribute self, ".i", $P10
165 .sub 'get_string' :vtable :method
166 getattribute $P10, self, ".i"
175 pir_output_is( <<'CODE', <<'OUTPUT', "constructor - parents" );
178 subclass $P2, $P1, "Bar"
179 subclass $P3, $P2, "Baz"
189 .sub 'init' :vtable :method
197 .sub 'init' :vtable :method
203 .sub 'init' :vtable :method
207 .namespace [] # main again
224 pir_output_is( <<'CODE', <<'OUTPUT', "methods: self" );
279 pir_output_is( <<'CODE', <<'OUTPUT', "methods: self w arg" );
331 pir_output_is( <<'CODE', <<'OUTPUT', "methods: self w arg and ret" );
388 skip( "currently broken", 1 );
389 pasm_output_is( <<'CODE', <<'OUTPUT', "exceptions and different runloops" );
398 print "back in main\n"
406 callmethodcc self, "qux"
417 pasm_output_is( <<'CODE', <<'OUTPUT', "find_method" );
422 find_method P0, P2, S0
429 .pcc_sub :method meth:
438 pasm_error_output_like( <<'CODE', <<'OUTPUT', "find_method - unknown method" );
441 find_method P0, P2, S0
445 /Method 'nada' not found for invocant of class 'Foo'/
448 pir_output_is( <<'CODE', <<'OUTPUT', "constructor - diamond parents" );
459 subclass $P3, $P1, "C"
462 subclass $P4, $P1, "D"
466 subclass $P6, $P3, "F"
520 .sub 'init' :vtable :method
526 .sub 'init' :vtable :method
532 .sub 'init' :vtable :method
538 .sub 'init' :vtable :method
544 .sub 'init' :vtable :method
550 .sub 'init' :vtable :method
578 pir_output_is( <<'CODE', <<'OUTPUT', "constructor - vtable override" );
581 $P1 = subclass 'Foo', 'Bar'
586 .sub init :vtable :method
591 .sub init :vtable :method
600 pir_output_is( <<'CODE', <<'OUTPUT', "same method name in two namespaces" );
626 pir_output_is( <<'CODE', <<'OUTPUT', "self - CURRENT_OBJECT" );
640 .include "interpinfo.pasm"
641 $P0 = interpinfo .INTERPINFO_CURRENT_OBJECT
642 eq_addr self, $P0, ok
650 pir_output_is( <<'CODE', <<'OUTPUT', "Bug in method calling with nonconst keys" );
667 .sub get_integer_keyed :vtable :method
679 pir_output_is( <<'CODE', <<'OUTPUT', "Bug in method calling with nonconst keys - clobber" );
696 .sub get_integer_keyed :vtable :method
713 pir_output_is( <<'CODE', <<'OUTPUT', "method cache invalidation" );
717 subclass cl, cl, "Bar"
720 $P0 = get_global "ok2"
721 cl.'add_vtable_override'('get_string', $P0)
728 .sub get_string :vtable :method
736 pir_output_is( <<'CODE', <<'OUTPUT', "callmethod - method name" );
764 skip( "no bound NCI method", 1 );
765 pir_output_is( <<'CODE', <<'OUTPUT', "bound NCI method" );
770 f = getattribute s, "lower"
783 pir_output_is( <<'CODE', <<'OUTPUT', "tailcallmeth" );
791 setattribute o, [ "Foo" ], "n", n
793 n = getattribute o, [ "Foo" ], "n"
801 n = getattribute self, [ "Foo" ], "n"
804 .tailcall self."go"()
811 pir_output_is( <<'CODE', <<'OUTPUT', "kind of a super" );
814 cl = subclass "String", "MyString"
821 .namespace ["MyString"]
822 .sub set_string_native :vtable :method
824 $P0 = getattribute self, ["String"], 'proxy'
832 pir_output_is( <<'CODE', <<'OUTPUT', "delegate keyed_int" );
835 cl = newclass "MyClass"
849 .namespace ["MyClass"]
851 .sub set_integer_keyed_int :vtable :method
857 .sub set_integer_keyed :vtable :method
863 .sub delete_keyed_int :vtable :method
868 .sub delete_keyed :vtable :method
873 .sub defined_keyed_int :vtable :method
879 .sub defined_keyed :vtable :method
885 .sub exists_keyed_int :vtable :method
887 print "exists_ikey\n"
891 .sub exists_keyed :vtable :method
893 print "exists_skey\n"
908 pir_output_is( <<'CODE', <<'OUTPUT', "delegate keyed_int PMC derived" );
911 cl = subclass "ResizablePMCArray", "MyClass"
920 .namespace ["MyClass"]
922 .sub get_integer_keyed_int :vtable :method
926 ar = getattribute self, ["ResizablePMCArray"], "proxy"
931 .sub set_integer_keyed_int :vtable :method
936 ar = getattribute self, ["ResizablePMCArray"], "proxy"
946 pir_output_is( <<'CODE', <<'OUTPUT', "delegate keyed_int PMC derived - inherit" );
949 cl = subclass "ResizablePMCArray", "MyClass"
958 .namespace ["MyClass"]
960 .sub get_integer_keyed_int :vtable :method
964 ar = getattribute self, ["ResizablePMCArray"], "proxy"
974 pir_output_is( <<'CODE', <<'OUTPUT', "addmethod op" );
977 c = newclass ['whatever']
978 .const 'Sub' foo = "whatever_foo"
979 addmethod c, "foo", foo
980 $P0 = new ['whatever']
984 .sub whatever_foo :anon :method
991 pir_output_is( <<'CODE', <<'OUTPUT', "inherit a PMC METHOD" );
994 cl = subclass 'Integer', 'MyInt'
997 $S0 = o.'get_as_base'(16)
1005 pir_output_is( <<'CODE', <<'OUTPUT', "init calls" );
1008 cl = newclass 'MyClass'
1010 $P0 = new ['String']
1011 o = new ['MyClass'], $P0
1014 .namespace ['MyClass']
1016 .sub init :method :vtable
1017 .param pmc initializer :optional
1018 print "init was called\n"
1021 .sub init_pmc :method :vtable
1022 .param pmc initializer
1023 print "init_pmc was called\n"
1030 pir_output_is( <<'CODE', <<'OUTPUT', "overloading find_method vtable" );
1033 cl = newclass 'MyClass'
1038 .namespace ['MyClass']
1040 .sub find_method :method :vtable
1041 .param string methodname
1042 print "find_method was called\n"
1043 $P0 = get_hll_global ["MyClass"], methodname
1048 print "foo was called\n"
1052 find_method was called
1056 pir_output_is( <<'CODE', <<'OUTPUT', "overloading attribute accessor vtable" );
1059 cl = newclass 'MyClass'
1061 $P2 = new ['String']
1063 setattribute o, "blue", $P2
1064 $P1 = getattribute o, "blue"
1067 .namespace ['MyClass']
1069 .sub get_attr_str :method :vtable
1070 .param string attrname
1071 print "get_attr_str was called\n"
1073 .sub set_attr_str :method :vtable
1074 .param string attrname
1076 print "set_attr_str was called\n"
1079 set_attr_str was called
1080 get_attr_str was called
1083 pir_error_output_like( <<'CODE', <<'OUTPUT', "method called on non-object" );
1084 .namespace [ 'Foo' ]
1092 $P1 = get_hll_global 'Foo'
1096 /Method 'new' not found for non-object/
1101 # cperl-indent-level: 4
1104 # vim: expandtab shiftwidth=4: