]> gitweb.factorcode.org Git - factor.git/blob - library/compiler/alien/objc/subclassing.factor
927984a1523649c0cb8836a3a8640727752d8b5d
[factor.git] / library / compiler / alien / objc / subclassing.factor
1 ! Copyright (C) 2006 Slava Pestov
2 ! See http://factorcode.org/license.txt for BSD license.
3 IN: objc
4 USING: alien arrays compiler hashtables kernel kernel-internals
5 libc math namespaces sequences strings words ;
6
7 : init-method ( method alien -- )
8     >r first3 r>
9     [ >r execute r> set-objc-method-imp ] keep
10     [ >r <malloc-string> r> set-objc-method-types ] keep
11     >r sel_registerName r> set-objc-method-name ;
12
13 : <empty-method-list> ( n -- alien )
14     "objc-method-list" c-size
15     "objc-method" c-size pick * + 1 calloc
16     [ set-objc-method-list-count ] keep ;
17
18 : <method-list> ( methods -- alien )
19     dup length dup <empty-method-list> -rot
20     [ pick method-list@ objc-method-nth init-method ] 2each ;
21
22 : <method-lists> ( methods -- lists )
23     <method-list> alien-address
24     "void*" <malloc-object> [ 0 set-alien-unsigned-cell ] keep ;
25
26 : <objc-class> ( name info -- class )
27     "objc-class" <malloc-object>
28     [ set-objc-class-info ] keep
29     [ >r <malloc-string> r> set-objc-class-name ] keep ;
30
31 ! The Objective C object model is a bit funny.
32 ! Every class has a metaclass.
33
34 ! The superclass of the metaclass of X is the metaclass of the
35 ! superclass of X.
36
37 ! The metaclass of the metaclass of X is the metaclass of the
38 ! root class of X.
39 : meta-meta-class ( class -- class ) root-class objc-class-isa ;
40
41 : copy-instance-size ( class -- )
42     dup objc-class-super-class objc-class-instance-size
43     swap set-objc-class-instance-size ;
44
45 : <meta-class> ( methods superclass name -- class )
46     CLS_META <objc-class>
47     [ >r dup objc-class-isa r> set-objc-class-super-class ] keep
48     [ >r meta-meta-class r> set-objc-class-isa ] keep
49     [ >r <method-lists> r> set-objc-class-methodLists ] keep
50     dup copy-instance-size ;
51
52 : <new-class> ( methods metaclass superclass name -- class )
53     CLS_CLASS <objc-class>
54     [ set-objc-class-super-class ] keep
55     [ set-objc-class-isa ] keep
56     [ >r <method-lists> r> set-objc-class-methodLists ] keep
57     dup copy-instance-size ;
58
59 : (define-objc-class) ( imeth cmeth superclass name -- )
60     >r objc-class r> [ <meta-class> ] 2keep <new-class>
61     objc_addClass ;
62
63 : encode-types ( return types -- encoding )
64     >r 1array r> append
65     [ [ alien>objc-types get hash % CHAR: 0 , ] each ] "" make ;
66
67 : struct-return ( ret types quot -- ret types quot )
68     pick c-struct? [
69         pick c-size [ memcpy ] curry append
70         >r { "void*" } swap append >r drop "void" r> r>
71     ] when ;
72
73 : prepare-method ( ret types quot -- type imp )
74     >r [ encode-types ] 2keep r>
75     [ struct-return 3array % \ alien-callback , ] [ ] make
76     compile-quot ;
77
78 : prepare-methods ( methods -- methods )
79     [ first4 prepare-method 3array ] map ;
80
81 : define-objc-class ( superclass name imeth cmeth -- )
82     pick >r
83     [ prepare-methods ] 2apply
84     [ 2array % 2array % \ (define-objc-class) , ] [ ] make
85     r> swap import-objc-class ;