1 /*
2 class.c
3
4 QC class support code
5
6 Copyright (C) 2002 Bill Currie
7
8 Author: Bill Currie <bill@taniwha.org>
9 Date: 2002/5/7
10
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License
13 as published by the Free Software Foundation; either version 2
14 of the License, or (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19
20 See the GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to:
24
25 Free Software Foundation, Inc.
26 59 Temple Place - Suite 330
27 Boston, MA 02111-1307, USA
28
29 */
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #ifdef HAVE_STRING_H
35 # include <string.h>
36 #endif
37 #ifdef HAVE_STRINGS_H
38 # include <strings.h>
39 #endif
40 #include <stdlib.h>
41
42 #include "QF/dstring.h"
43 #include "QF/hash.h"
44 #include "QF/pr_obj.h"
45 #include "QF/va.h"
46
47 #include "qfcc.h"
48
49 #include "codespace.h"
50 #include "class.h"
51 #include "def.h"
52 #include "defspace.h"
53 #include "diagnostic.h"
54 #include "emit.h"
55 #include "expr.h"
56 #include "method.h"
57 #include "options.h"
58 #include "reloc.h"
59 #include "shared.h"
60 #include "strpool.h"
61 #include "struct.h"
62 #include "symtab.h"
63 #include "type.h"
64 #include "value.h"
65
66 static hashtab_t *class_hash;
67 static hashtab_t *category_hash;
68 static hashtab_t *protocol_hash;
69
70 // these will be built up further
71 type_t type_obj_selector = { ev_invalid, 0, ty_struct};
72 type_t type_SEL = { ev_pointer, "SEL", ty_none, {{&type_obj_selector}}};
73 type_t type_IMP = { ev_func, "IMP", ty_none,
74 {{&type_id, -3, {&type_id, &type_SEL}}}};
75 type_t type_obj_super = { ev_invalid, 0 };
76 type_t type_SuperPtr = { ev_pointer, 0, ty_none, {{&type_obj_super}}};
77 type_t type_supermsg = { ev_func, ".supermsg", ty_none,
78 {{&type_id, -3, {&type_SuperPtr, &type_SEL}}}};
79 type_t type_obj_method = { ev_invalid, 0, ty_struct };
80 type_t type_obj_method_description = { ev_invalid, 0, ty_struct };
81 type_t type_obj_category = { ev_invalid, 0, ty_struct};
82 type_t type_obj_ivar = { ev_invalid, 0, ty_struct};
83 type_t type_obj_module = { ev_invalid, 0, ty_struct};
84 type_t type_moduleptr = { ev_pointer, 0, ty_none, {{&type_obj_module}}};
85 type_t type_obj_exec_class = { ev_func, 0, ty_none,
86 {{&type_void, 1, { &type_moduleptr }}}};
87
88 type_t type_obj_object = {ev_invalid, 0, ty_struct};
89 type_t type_id = { ev_pointer, "id", ty_none, {{&type_obj_object}}};
90 type_t type_obj_class = { ev_invalid, 0, ty_struct};
91 type_t type_Class = { ev_pointer, 0, ty_none, {{&type_obj_class}}};
92 type_t type_obj_protocol = { ev_invalid, 0, ty_struct};
93
94 int obj_initialized = 0;
95
96 static struct_def_t sel_struct[] = {
97 {"sel_id", &type_string},
98 {"sel_types", &type_string},
99 {0, 0}
100 };
101
102 static struct_def_t method_struct[] = {
103 {"method_name", &type_SEL},
104 {"method_types", &type_string},
105 {"method_imp", &type_IMP},
106 {0, 0}
107 };
108
109 static struct_def_t method_desc_struct[] = {
110 {"name", &type_string},
111 {"types", &type_string},
112 {0, 0}
113 };
114
115 static struct_def_t category_struct[] = {
116 {"category_name", &type_string},
117 {"class_name", &type_string},
118 {"instance_methods", &type_pointer},
119 {"class_methods", &type_pointer},
120 {"protocols", &type_pointer},
121 {0, 0}
122 };
123
124 static struct_def_t ivar_struct[] = {
125 {"ivar_name", &type_string},
126 {"ivar_type", &type_string},
127 {"ivar_offset", &type_integer},
128 {0, 0}
129 };
130
131 static struct_def_t super_struct[] = {
132 {"self", &type_id},
133 {"class", &type_Class},
134 {0, 0}
135 };
136
137 static struct_def_t module_struct[] = {
138 {"version", &type_integer},
139 {"size", &type_integer},
140 {"name", &type_string},
141 {"symtab", &type_pointer},
142 {0, 0}
143 };
144
145 static struct_def_t class_struct[] = {
146 {"class_pointer", &type_Class},
147 {"super_class", &type_Class},
148 {"name", &type_string},
149 {"version", &type_integer},
150 {"info", &type_integer},
151 {"instance_size", &type_integer},
152 {"ivars", &type_pointer},
153 {"methods", &type_pointer},
154 {"dtable", &type_pointer},
155 {"subclass_list", &type_pointer},
156 {"sibling_class", &type_pointer},
157 {"protocols", &type_pointer},
158 {"gc_object_type", &type_pointer},
159 {0, 0}
160 };
161
162 static struct_def_t protocol_struct[] = {
163 {"class_pointer", &type_Class},
164 {"protocol_name", &type_string},
165 {"protocol_list", &type_pointer},
166 {"instance_methods", &type_pointer},
167 {"class_methods", &type_pointer},
168 {0, 0}
169 };
170
171 static struct_def_t object_struct[] = {
172 {"class_pointer", &type_Class},
173 {0, 0}
174 };
175
176 int
obj_is_id(const type_t * type)177 obj_is_id (const type_t *type)
178 {
179 if (type == &type_id)
180 return 1;
181 // type may be a qualified id, in which case it will be a pointer to
182 // a qualified obj_object struct
183 if (type->type != ev_pointer)
184 return 0;
185 if (!is_struct (type->t.fldptr.type))
186 return 0;
187 // if the the symtabs match, then type is id in disguise
188 if (type->t.fldptr.type->t.symtab == type_obj_object.t.symtab)
189 return 1;
190 return 0;
191 }
192
193 int
obj_is_class(const type_t * type)194 obj_is_class (const type_t *type)
195 {
196 if (type->type == ev_invalid && type->meta == ty_class)
197 return 1;
198 return 0;
199 }
200
201 int
obj_is_Class(const type_t * type)202 obj_is_Class (const type_t *type)
203 {
204 if (type == &type_Class)
205 return 1;
206 // type may be a qualified Class, in which case it will be a pointer to
207 // a qualified obj_class struct
208 if (type->type != ev_pointer)
209 return 0;
210 if (!is_struct (type->t.fldptr.type))
211 return 0;
212 // if the the symtabs match, then type is Class in disguise
213 if (type->t.fldptr.type->t.symtab == type_obj_class.t.symtab)
214 return 1;
215 return 0;
216 }
217
218 int
obj_is_classptr(const type_t * type)219 obj_is_classptr (const type_t *type)
220 {
221 // easy cases first :)
222 if (obj_is_id (type) || obj_is_Class (type))
223 return 1;
224 if (type->type != ev_pointer)
225 return 0;
226 type = type->t.fldptr.type;
227 if (obj_is_class (type))
228 return 1;
229 return 0;
230 }
231
232 static protocollist_t *
obj_get_class_protos(const type_t * type)233 obj_get_class_protos (const type_t *type)
234 {
235 if (is_pointer (type))
236 type = type->t.fldptr.type;
237 if (obj_is_class (type))
238 return type->t.class->protocols;
239 return 0;
240 }
241
242 static protocollist_t *
obj_get_protos(const type_t * type)243 obj_get_protos (const type_t *type)
244 {
245 if (is_pointer (type))
246 type = type->t.fldptr.type;
247 return type->protos;
248 }
249
250 static category_t *
obj_get_categories(const type_t * type)251 obj_get_categories (const type_t *type)
252 {
253 if (is_pointer (type))
254 type = type->t.fldptr.type;
255 if (obj_is_class (type))
256 return type->t.class->categories;
257 return 0;
258 }
259
260 static const char *
obj_classname(const type_t * type)261 obj_classname (const type_t *type)
262 {
263 static dstring_t *str;
264 protocollist_t *protos;
265
266 if (!str)
267 str = dstring_new ();
268 dstring_clearstr (str);
269 if (obj_is_id (type)) {
270 dstring_copystr (str, "id");
271 } else if (obj_is_Class (type)) {
272 dstring_copystr (str, "Class");
273 } else {
274 if (is_pointer (type))
275 type = type->t.fldptr.type;
276 if (obj_is_class (type))
277 dstring_copystr (str, type->t.class->name);
278 }
279 if ((protos = obj_get_protos (type)))
280 print_protocollist (str, protos);
281 return str->str;
282 }
283
284 static int
category_implements(category_t * cat,protocol_t * protocol)285 category_implements (category_t *cat, protocol_t *protocol)
286 {
287 for (; cat; cat = cat->next) {
288 if (!cat->protocols)
289 continue;
290 if (procollist_find_protocol (cat->protocols, protocol))
291 return 1;
292 }
293 return 0;
294 }
295
296 int
obj_types_assignable(const type_t * dst,const type_t * src)297 obj_types_assignable (const type_t *dst, const type_t *src)
298 {
299 class_t *dst_class, *src_class;
300 category_t *cat;
301 int dst_is_proto, src_is_proto;
302 protocollist_t *dst_protos = 0, *src_protos = 0;
303 int i;
304
305 //puts ("%$$\"$#%");
306 if (!obj_is_classptr (dst) || !obj_is_classptr (src))
307 return -1;
308
309 dst_is_proto = obj_is_id (dst) && (dst_protos = obj_get_protos (dst));
310 src_is_proto = obj_is_id (src) && (src_protos = obj_get_protos (src));
311
312 if (dst_is_proto) {
313 if (src_is_proto) {
314 // id <protos> = id <protos>
315 for (i = 0; i < dst_protos->count; i++) {
316 if (!procollist_find_protocol (src_protos,
317 dst_protos->list[i])) {
318 warning (0, "type %s does not conform to the %s protocol",
319 obj_classname (src), dst_protos->list[i]->name);
320 return 1;
321 }
322 }
323 } else if (!obj_is_id (src)) {
324 src_protos = obj_get_class_protos (src);
325 for (i = 0; i < dst_protos->count; i++) {
326 if (procollist_find_protocol (src_protos, dst_protos->list[i]))
327 continue;
328 cat = obj_get_categories (src);
329 if (cat && category_implements (cat, dst_protos->list[i]))
330 continue;
331 warning (0, "class %s does not implement to the %s protocol",
332 obj_classname (src), dst_protos->list[i]->name);
333 return 1;
334 }
335 return 1;
336 }
337 } else if (src_is_proto) {
338 } else {
339 }
340 if (obj_is_id (dst) || obj_is_id (src))
341 return 1;
342
343 // check dst is a base class of src
344 dst_class = dst->t.fldptr.type->t.class;
345 src_class = src->t.fldptr.type->t.class;
346 //printf ("%s %s\n", dst_class->name, src_class->name);
347 while (dst_class != src_class && src_class) {
348 src_class = src_class->super_class;
349 //if (src_class)
350 // printf ("%s %s\n", dst_class->name, src_class->name);
351 }
352 if (dst_class == src_class)
353 return 1;
354 return 0;
355 }
356
357 static const char *
class_get_key(const void * class,void * unused)358 class_get_key (const void *class, void *unused)
359 {
360 return ((class_t *) class)->name;
361 }
362
363 static const char *
protocol_get_key(const void * protocol,void * unused)364 protocol_get_key (const void *protocol, void *unused)
365 {
366 return ((protocol_t *) protocol)->name;
367 }
368
369 const char *
get_class_name(class_type_t * class_type,int pretty)370 get_class_name (class_type_t *class_type, int pretty)
371 {
372 switch (class_type->type) {
373 case ct_class:
374 if (pretty)
375 return class_type->c.class->name;
376 else
377 return va ("%s_", class_type->c.class->name);
378 case ct_category:
379 if (pretty)
380 return va ("%s (%s)", class_type->c.category->class->name,
381 class_type->c.category->name);
382 else
383 return va ("%s_%s", class_type->c.category->class->name,
384 class_type->c.category->name);
385 case ct_protocol:
386 return va ("<%s>", class_type->c.protocol->name);
387 }
388 return "???";
389 }
390
391 symbol_t *
class_symbol(class_type_t * class_type,int external)392 class_symbol (class_type_t *class_type, int external)
393 {
394 const char *name = 0;
395 type_t *type = 0;
396 symbol_t *sym;
397
398 switch (class_type->type) {
399 case ct_category:
400 name = va ("_OBJ_CATEGORY_%s_%s",
401 class_type->c.category->class->name,
402 class_type->c.category->name);
403 type = &type_obj_category;
404 break;
405 case ct_class:
406 name = va ("_OBJ_CLASS_%s", class_type->c.class->name);
407 type = &type_obj_class;
408 break;
409 case ct_protocol:
410 return 0; // probably in error recovery
411 }
412 sym = make_symbol (name, type, pr.far_data,
413 external ? sc_extern : sc_global);
414 if (!sym->table)
415 symtab_addsymbol (pr.symtab, sym);
416 return sym;
417 }
418
419 static class_t *
_get_class(symbol_t * sym,int create)420 _get_class (symbol_t *sym, int create)
421 {
422 class_t *c;
423
424 if (!class_hash)
425 class_hash = Hash_NewTable (1021, class_get_key, 0, 0);
426 if (sym) {
427 c = Hash_Find (class_hash, sym->name);
428 if (c || !create)
429 return c;
430 }
431
432 c = calloc (sizeof (class_t), 1);
433 c->methods = new_methodlist ();
434 c->class_type.type = ct_class;
435 c->class_type.c.class = c;
436 if (sym) {
437 c->name = sym->name;
438 Hash_Add (class_hash, c);
439 sym->sy_type = sy_class;
440 }
441
442 sym = class_symbol (&c->class_type, 1);
443 c->def = sym->s.def;
444
445 return c;
446 }
447
448 class_t *
get_class(symbol_t * sym,int create)449 get_class (symbol_t *sym, int create)
450 {
451 class_t *c;
452 type_t new;
453
454 if (!(c = _get_class (sym, create)))
455 return c;
456
457 memset (&new, 0, sizeof (new));
458 new.type = ev_invalid;
459 new.name = c->name;
460 new.meta = ty_class;
461 new.t.class = c;
462 c->type = find_type (&new);
463 if (sym)
464 sym->type = c->type;
465 return c;
466 }
467
468 static void
set_self_type(class_t * class,method_t * method)469 set_self_type (class_t *class, method_t *method)
470 {
471 if (method->instance)
472 method->params->type = pointer_type (class->type);
473 else
474 method->params->type = &type_Class;
475 }
476
477 static void
methods_set_self_type(class_t * class,methodlist_t * methods)478 methods_set_self_type (class_t *class, methodlist_t *methods)
479 {
480 method_t *method;
481
482 for (method = methods->head; method; method = method->next)
483 set_self_type (class, method);
484 }
485
486 void
class_add_methods(class_t * class,methodlist_t * methods)487 class_add_methods (class_t *class, methodlist_t *methods)
488 {
489 if (!methods)
490 return;
491
492 *class->methods->tail = methods->head;
493 class->methods->tail = methods->tail;
494 free (methods);
495
496 methods_set_self_type (class, class->methods);
497 }
498
499 void
class_add_protocols(class_t * class,protocollist_t * protocols)500 class_add_protocols (class_t *class, protocollist_t *protocols)
501 {
502 int i;
503 protocol_t *p;
504 methodlist_t *methods;
505
506 if (!protocols)
507 return;
508
509 methods = class->methods;
510
511 for (i = 0; i < protocols->count; i++) {
512 p = protocols->list[i];
513 copy_methods (methods, p->methods);
514 if (p->protocols)
515 class_add_protocols (class, p->protocols);
516 }
517 class->protocols = protocols;
518 }
519
520 static void
begin_category(category_t * category)521 begin_category (category_t *category)
522 {
523 pr_category_t *pr_category;
524 class_t *class = category->class;
525 symbol_t *sym;
526 def_t *def;
527 defspace_t *space;
528
529 current_class = &category->class_type;
530 sym = class_symbol (current_class, 0);
531 category->def = def = sym->s.def;
532 def->initialized = def->constant = def->nosave = 1;
533 space = def->space;
534
535 pr_category = &D_STRUCT (pr_category_t, def);
536 EMIT_STRING (space, pr_category->category_name, category->name);
537 EMIT_STRING (space, pr_category->class_name, class->name);
538 EMIT_DEF (space, pr_category->protocols,
539 emit_protocol_list (category->protocols,
540 va ("%s_%s", class->name, category->name)));
541 }
542
543 typedef struct {
544 int count;
545 symbol_t *ivars;
546 dstring_t *encoding;
547 } ivar_data_t;
548
549 static void
emit_ivar_count(def_t * def,void * data,int index)550 emit_ivar_count (def_t *def, void *data, int index)
551 {
552 ivar_data_t *ivar_data = (ivar_data_t *) data;
553
554 if (def->type != &type_integer)
555 internal_error (0, "%s: expected integer def", __FUNCTION__);
556 D_INT (def) = ivar_data->count;
557 }
558
559 static void
emit_ivar_list_item(def_t * def,void * data,int index)560 emit_ivar_list_item (def_t *def, void *data, int index)
561 {
562 ivar_data_t *ivar_data = (ivar_data_t *) data;
563 symbol_t *ivar_sym;
564 pr_ivar_t *ivar;
565 defspace_t *space;
566
567 #if 0
568 //FIXME the type is dynamic, so need a way to pass it before it cn be
569 //checked
570 if (def->type != &XXX)
571 internal_error (0, "%s: expected XXX def",
572 __FUNCTION__);
573 #endif
574 if (index < 0 || index >= ivar_data->count)
575 internal_error (0, "%s: out of bounds index: %d %d",
576 __FUNCTION__, index, ivar_data->count);
577
578 for (ivar_sym = ivar_data->ivars; ivar_sym; ivar_sym = ivar_sym->next) {
579 if (ivar_sym->sy_type != sy_var)
580 continue;
581 if (!index--)
582 break;
583 }
584
585 ivar = D_POINTER (pr_ivar_t, def);
586 space = def->space;
587 dstring_clearstr (ivar_data->encoding);
588
589 EMIT_STRING (space, ivar->ivar_name, ivar_sym->name);
590 encode_type (ivar_data->encoding, ivar_sym->type);
591 EMIT_STRING (space, ivar->ivar_type, ivar_data->encoding->str);
592 ivar->ivar_offset = ivar_sym->s.offset;
593 }
594
595 static def_t *
emit_ivars(symtab_t * ivars,const char * name)596 emit_ivars (symtab_t *ivars, const char *name)
597 {
598 static struct_def_t ivar_list_struct[] = {
599 {"ivar_count", &type_integer, emit_ivar_count},
600 {"ivar_list", 0, emit_ivar_list_item},
601 {0, 0}
602 };
603 ivar_data_t ivar_data = {0, 0, 0};
604 symbol_t *s;
605 def_t *def;
606
607 ivar_data.encoding = dstring_newstr ();
608 if (ivars) {
609 ivar_data.ivars = ivars->symbols;
610 for (s = ivars->symbols; s; s = s->next)
611 if (s->sy_type == sy_var)
612 ivar_data.count++;
613 }
614 ivar_list_struct[1].type = array_type (&type_obj_ivar, ivar_data.count);
615
616 def = emit_structure (va ("_OBJ_INSTANCE_VARIABLES_%s", name), 's',
617 ivar_list_struct, 0, &ivar_data, sc_static);
618
619 dstring_delete (ivar_data.encoding);
620 return def;
621 }
622
623 static void
begin_class(class_t * class)624 begin_class (class_t *class)
625 {
626 def_t *meta_def;
627 pr_class_t *meta;
628 pr_class_t *pr_class;
629 symbol_t *sym;
630 def_t *def;
631 defspace_t *space;
632
633 sym = make_symbol (va ("_OBJ_METACLASS_%s", class->name),
634 &type_obj_class, pr.far_data, sc_static);
635 meta_def = sym->s.def;
636 meta_def->initialized = meta_def->constant = meta_def->nosave = 1;
637 space = meta_def->space;
638 meta = &D_STRUCT (pr_class_t, meta_def);
639 EMIT_STRING (space, meta->class_pointer, class->name);
640 if (class->super_class)
641 EMIT_STRING (space, meta->super_class, class->super_class->name);
642 EMIT_STRING (space, meta->name, class->name);
643 meta->info = _PR_CLS_META;
644 meta->instance_size = type_size (&type_obj_class);
645 EMIT_DEF (space, meta->ivars,
646 emit_ivars (type_obj_class.t.class->ivars, "Class"));
647 current_class = &class->class_type;
648 sym = class_symbol (current_class, 0);
649 class->def = def = sym->s.def;
650 def->initialized = def->constant = def->nosave = 1;
651 space = def->space;
652
653 pr_class = &D_STRUCT (pr_class_t, def);
654 EMIT_DEF (space, pr_class->class_pointer, meta_def);
655 if (class->super_class) {
656 class_type_t class_type = {ct_class, {0}};
657 class_type.c.class = class->super_class;
658 EMIT_STRING (space, pr_class->super_class, class->super_class->name);
659 class_symbol (&class_type, 1);
660 }
661 EMIT_STRING (space, pr_class->name, class->name);
662 pr_class->info = _PR_CLS_CLASS;
663 EMIT_DEF (space, pr_class->protocols,
664 emit_protocol_list (class->protocols, class->name));
665 }
666
667 void
class_begin(class_type_t * class_type)668 class_begin (class_type_t *class_type)
669 {
670 if (current_class) {
671 warning (0, "‘@end’ missing in implementation context");
672 class_finish (current_class);
673 current_class = 0;
674 }
675 switch (class_type->type) {
676 case ct_category:
677 begin_category (class_type->c.category);
678 break;
679 case ct_class:
680 begin_class (class_type->c.class);
681 break;
682 case ct_protocol:
683 return; // probably error recovery
684 }
685 }
686
687 void
emit_class_ref(const char * class_name)688 emit_class_ref (const char *class_name)
689 {
690 symbol_t *ref_sym;
691 symbol_t *name_sym;
692 def_t *ref_def;
693 def_t *name_def;
694
695 ref_sym = make_symbol (va (".obj_class_ref_%s", class_name), &type_pointer,
696 pr.far_data, sc_static);
697 if (!ref_sym->table)
698 symtab_addsymbol (pr.symtab, ref_sym);
699 ref_def = ref_sym->s.def;
700 if (ref_def->initialized)
701 return;
702 ref_def->initialized = ref_def->constant = ref_def->nosave = 1;
703 name_sym = make_symbol (va (".obj_class_name_%s", class_name),
704 &type_pointer, pr.far_data, sc_extern);
705 if (!name_sym->table)
706 symtab_addsymbol (pr.symtab, name_sym);
707 name_def = name_sym->s.def;
708 if (!name_def->external)
709 D_INT (ref_def) = name_def->offset;
710 reloc_def_def (name_def, ref_def);
711 }
712
713 static void
emit_class_name(const char * class_name)714 emit_class_name (const char *class_name)
715 {
716 symbol_t *name_sym;
717 def_t *name_def;
718
719 name_sym = make_symbol (va (".obj_class_name_%s", class_name),
720 &type_pointer, pr.far_data, sc_global);
721 if (!name_sym->table)
722 symtab_addsymbol (pr.symtab, name_sym);
723 name_def = name_sym->s.def;
724 if (name_def->initialized)
725 return;
726 name_def->initialized = name_def->constant = 1;
727 name_def->nosave = 1;
728 D_INT (name_def) = 0;
729 }
730
731 void
emit_category_ref(const char * class_name,const char * category_name)732 emit_category_ref (const char *class_name, const char *category_name)
733 {
734 symbol_t *ref_sym;
735 symbol_t *name_sym;
736 def_t *ref_def;
737 def_t *name_def;
738
739 ref_sym = make_symbol (va (".obj_category_ref_%s_%s",
740 class_name, category_name),
741 &type_pointer, pr.far_data, sc_static);
742 if (!ref_sym->table)
743 symtab_addsymbol (pr.symtab, ref_sym);
744 ref_def = ref_sym->s.def;
745 if (ref_def->initialized)
746 return;
747 ref_def->initialized = ref_def->constant = 1;
748 ref_def->nosave = 1;
749 name_sym = make_symbol (va (".obj_category_name_%s_%s",
750 class_name, category_name),
751 &type_pointer, pr.far_data, sc_extern);
752 if (!name_sym->table)
753 symtab_addsymbol (pr.symtab, name_sym);
754 name_def = name_sym->s.def;
755 if (!name_def->external)
756 D_INT (ref_def) = name_def->offset;
757 reloc_def_def (name_def, ref_def);
758 }
759
760 static void
emit_category_name(const char * class_name,const char * category_name)761 emit_category_name (const char *class_name, const char *category_name)
762 {
763 symbol_t *name_sym;
764 def_t *name_def;
765
766 name_sym = make_symbol (va (".obj_category_name_%s_%s",
767 class_name, category_name),
768 &type_pointer, pr.far_data, sc_global);
769 if (!name_sym->table)
770 symtab_addsymbol (pr.symtab, name_sym);
771 name_def = name_sym->s.def;
772 if (name_def->initialized)
773 return;
774 name_def->initialized = name_def->constant = 1;
775 name_def->nosave = 1;
776 D_INT (name_def) = 0;
777 }
778
779 static void
finish_category(category_t * category)780 finish_category (category_t *category)
781 {
782 pr_category_t *pr_category;
783 class_t *class = category->class;
784 char *name;
785 defspace_t *space;
786
787 if (!category->def) // probably in error recovery
788 return;
789 name = nva ("%s_%s", class->name, category->name);
790 pr_category = &D_STRUCT (pr_category_t, category->def);
791 space = category->def->space;
792 EMIT_DEF (space, pr_category->instance_methods,
793 emit_methods (category->methods, name, 1));
794 EMIT_DEF (space, pr_category->class_methods,
795 emit_methods (category->methods, name, 0));
796 free (name);
797 emit_class_ref (class->name);
798 emit_category_name (class->name, category->name);
799 }
800
801 static void
finish_class(class_t * class)802 finish_class (class_t *class)
803 {
804 pr_class_t *meta;
805 pr_class_t *cls;
806 defspace_t *space;
807
808 if (pr.error_count) // probably in error recovery
809 return;
810 space = class->def->space;
811 cls = &D_STRUCT (pr_class_t, class->def);
812
813 meta = &G_STRUCT (space, pr_class_t, cls->class_pointer);
814
815 EMIT_DEF (space, meta->methods, emit_methods (class->methods,
816 class->name, 0));
817
818 cls->instance_size = type_size (class->type);
819 EMIT_DEF (space, cls->ivars, emit_ivars (class->ivars, class->name));
820 EMIT_DEF (space, cls->methods, emit_methods (class->methods,
821 class->name, 1));
822 if (class->super_class)
823 emit_class_ref (class->super_class->name);
824 emit_class_name (class->name);
825 }
826
827 void
class_finish(class_type_t * class_type)828 class_finish (class_type_t *class_type)
829 {
830 switch (class_type->type) {
831 case ct_category:
832 finish_category (class_type->c.category);
833 break;
834 case ct_class:
835 finish_class (class_type->c.class);
836 break;
837 case ct_protocol:
838 return; // probably in error recovery
839 }
840 }
841
842 class_t *
extract_class(class_type_t * class_type)843 extract_class (class_type_t *class_type)
844 {
845 switch (class_type->type) {
846 case ct_class:
847 return current_class->c.class;
848 case ct_category:
849 return current_class->c.category->class;
850 case ct_protocol:
851 return 0; // probably in error recovery
852 }
853 return 0; // should not happen
854 }
855
856 int
class_access(class_type_t * class_type,class_t * class)857 class_access (class_type_t *class_type, class_t *class)
858 {
859 class_t *cur;
860 if (class_type) {
861 if (!(cur = extract_class (class_type)))
862 return vis_private;
863 if (cur == class)
864 return vis_private;
865 cur = cur->super_class;
866 while (cur) {
867 if (cur == class)
868 return vis_protected;
869 cur = cur->super_class;
870 }
871 }
872 return vis_public;
873 }
874
875 symbol_t *
class_find_ivar(class_t * class,int vis,const char * name)876 class_find_ivar (class_t *class, int vis, const char *name)
877 {
878 symbol_t *ivar;
879
880 ivar = symtab_lookup (class->ivars, name);
881 if (ivar) {
882 if (ivar->visibility > (vis_t) vis)
883 goto access_error;
884 return ivar;
885 }
886 error (0, "%s.%s does not exist", class->name, name);
887 return 0;
888 access_error:
889 error (0, "%s.%s is not accessable here", class->name, name);
890 return 0;
891 }
892
893 method_t *
class_find_method(class_type_t * class_type,method_t * method)894 class_find_method (class_type_t *class_type, method_t *method)
895 {
896 methodlist_t *methods = 0, *start_methods;
897 method_t *m;
898 dstring_t *sel;
899 class_t *class = 0, *start_class;
900
901 switch (class_type->type) {
902 case ct_category:
903 methods = class_type->c.category->methods;
904 class = class_type->c.category->class;
905 break;
906 case ct_class:
907 class = class_type->c.class;
908 methods = class->methods;
909 break;
910 case ct_protocol:
911 return 0; // probably in error recovery
912 }
913 start_methods = methods;
914 start_class = class;
915 while (class) {
916 for (m = methods->head; m; m = m->next)
917 if (method_compare (method, m)) {
918 if (m->type != method->type)
919 error (0, "method type mismatch");
920 if (methods != start_methods) {
921 m = copy_method (m);
922 set_self_type (start_class, m);
923 add_method (start_methods, m);
924 }
925 method_set_param_names (m, method);
926 return m;
927 }
928 if (class->methods == methods)
929 class = class->super_class;
930 else
931 methods = class->methods;
932 }
933 sel = dstring_newstr ();
934 selector_name (sel, (keywordarg_t *)method->selector);
935 set_self_type (start_class, method);
936 add_method (start_methods, method);
937 dstring_delete (sel);
938 return method;
939 }
940
941 method_t *
class_message_response(class_t * class,int class_msg,expr_t * sel)942 class_message_response (class_t *class, int class_msg, expr_t *sel)
943 {
944 selector_t *selector;
945 method_t *m;
946 class_t *c = class;
947 category_t *cat;
948
949 selector = get_selector (sel);
950 if (!selector)
951 return 0;
952 if (class && class->type != &type_obj_object) {
953 while (c) {
954 for (cat = c->categories; cat; cat = cat->next) {
955 for (m = cat->methods->head; m; m = m->next) {
956 if (((!c->super_class && class_msg)
957 || class_msg != m->instance)
958 && strcmp (selector->name, m->name) == 0)
959 return m;
960 }
961 }
962 for (m = c->methods->head; m; m = m->next) {
963 if (((!c->super_class && class_msg)
964 || class_msg != m->instance)
965 && strcmp (selector->name, m->name) == 0)
966 return m;
967 }
968 c = c->super_class;
969 }
970 //FIXME right option?
971 if (options.warnings.interface_check)
972 warning (sel, "%s may not respond to %c%s", class->name,
973 class_msg ? '+' : '-', selector->name);
974 }
975 m = find_method (selector->name);
976 if (m)
977 return m;
978 //FIXME right option?
979 if (options.warnings.interface_check)
980 warning (sel, "could not find method for %c%s",
981 class_msg ? '+' : '-', selector->name);
982 return 0;
983 }
984
985 static uintptr_t
category_get_hash(const void * _c,void * unused)986 category_get_hash (const void *_c, void *unused)
987 {
988 category_t *c = (category_t *) _c;
989 return Hash_String (c->name) ^ Hash_String (c->class->name);
990 }
991
992 static int
category_compare(const void * _c1,const void * _c2,void * unused)993 category_compare (const void *_c1, const void *_c2, void *unused)
994 {
995 category_t *c1 = (category_t *) _c1;
996 category_t *c2 = (category_t *) _c2;
997 return strcmp (c1->name, c2->name) == 0
998 && strcmp (c1->class->name, c2->class->name) == 0;
999 }
1000
1001 symtab_t *
class_new_ivars(class_t * class)1002 class_new_ivars (class_t *class)
1003 {
1004 symtab_t *ivars;
1005 symtab_t *super_ivars = 0;
1006
1007 if (class->super_class)
1008 super_ivars = class->super_class->ivars;
1009 ivars = new_symtab (super_ivars, stab_local);
1010 return ivars;
1011 }
1012
1013 void
class_add_ivars(class_t * class,symtab_t * ivars)1014 class_add_ivars (class_t *class, symtab_t *ivars)
1015 {
1016 int base = 0;
1017 symbol_t *sym;
1018
1019 if (class->super_class)
1020 base = type_size (class->super_class->type);
1021 for (sym = ivars->symbols; sym; sym = sym->next)
1022 sym->s.offset += base;
1023 class->ivars = ivars;
1024 }
1025
1026 static int
compare_symbols(symbol_t * s1,symbol_t * s2)1027 compare_symbols (symbol_t *s1, symbol_t *s2)
1028 {
1029 if (s1->visibility != s2->visibility)
1030 return 0;
1031 if (s1->name != s2->name) // works thanks to save_string
1032 return 0;
1033 if (s1->sy_type != s2->sy_type)
1034 return 0;
1035 if (s1->type != s2->type)
1036 return 0;
1037 return 1;
1038 }
1039
1040 void
class_check_ivars(class_t * class,symtab_t * ivars)1041 class_check_ivars (class_t *class, symtab_t *ivars)
1042 {
1043 symbol_t *civ, *iv;
1044 int missmatch = 0;
1045
1046 if (!class->ivars != !ivars) {
1047 missmatch = 1;
1048 } else if (ivars) {
1049 for (civ = class->ivars->symbols, iv = ivars->symbols;
1050 civ && iv; civ = civ->next, iv = iv->next) {
1051 if (!compare_symbols (civ, iv)) {
1052 missmatch = 1;
1053 break;
1054 }
1055 }
1056 }
1057 //FIXME right option?
1058 if (missmatch && options.warnings.interface_check)
1059 warning (0, "instance variable missmatch for %s", class->name);
1060 class_add_ivars (class, ivars);
1061 }
1062
1063 category_t *
get_category(symbol_t * class_name,const char * category_name,int create)1064 get_category (symbol_t *class_name, const char *category_name, int create)
1065 {
1066 category_t *category;
1067 class_t *class;
1068
1069 if (!category_hash) {
1070 category_hash = Hash_NewTable (1021, 0, 0, 0);
1071 Hash_SetHashCompare (category_hash,
1072 category_get_hash, category_compare);
1073 }
1074 class = get_class (class_name, 0);
1075 if (!class) {
1076 error (0, "undefined class %s", class_name->name);
1077 return 0;
1078 }
1079 if (class_name && category_name) {
1080 category_t _c = {0, category_name, class};
1081
1082 category = Hash_FindElement (category_hash, &_c);
1083 if (category || !create)
1084 return category;
1085 }
1086
1087 category = calloc (sizeof (category_t), 1);
1088 category->next = class->categories;
1089 class->categories = category;
1090 category->name = category_name;
1091 category->class = class;
1092 category->methods = new_methodlist ();
1093 category->class_type.type = ct_category;
1094 category->class_type.c.category = category;
1095 if (class_name && category_name)
1096 Hash_AddElement (category_hash, category);
1097 return category;
1098 }
1099
1100 void
category_add_methods(category_t * category,methodlist_t * methods)1101 category_add_methods (category_t *category, methodlist_t *methods)
1102 {
1103 if (!methods)
1104 return;
1105 *category->methods->tail = methods->head;
1106 category->methods->tail = methods->tail;
1107 free (methods);
1108
1109 methods_set_self_type (category->class, category->methods);
1110 }
1111
1112 void
category_add_protocols(category_t * category,protocollist_t * protocols)1113 category_add_protocols (category_t *category, protocollist_t *protocols)
1114 {
1115 int i;
1116 protocol_t *p;
1117 methodlist_t *methods;
1118
1119 if (!protocols)
1120 return;
1121
1122 methods = category->methods;
1123
1124 for (i = 0; i < protocols->count; i++) {
1125 p = protocols->list[i];
1126 copy_methods (methods, p->methods);
1127 if (p->protocols)
1128 category_add_protocols (category, p->protocols);
1129 }
1130 category->protocols = protocols;
1131 }
1132
1133 symbol_t *
class_pointer_symbol(class_t * class)1134 class_pointer_symbol (class_t *class)
1135 {
1136 def_t *def;
1137 symbol_t *sym;
1138 class_type_t class_type = {ct_class, {0}};
1139
1140 class_type.c.class = class;
1141
1142 sym = make_symbol (va ("_OBJ_CLASS_POINTER_%s", class->name),
1143 &type_Class,
1144 pr.near_data, sc_static);
1145 if (!sym->table)
1146 symtab_addsymbol (pr.symtab, sym);
1147 def = sym->s.def;
1148 if (def->initialized)
1149 return sym;
1150 def->initialized = def->constant = 1;
1151 def->nosave = 1;
1152 if (!class->def)
1153 class->def = class_symbol (&class_type, 1)->s.def;
1154 if (!class->def->external)
1155 D_INT (def) = class->def->offset;
1156 reloc_def_def (class->def, def);
1157 return sym;
1158 }
1159
1160
1161 typedef struct {
1162 def_t *refs;
1163 class_t **classes;
1164 int cls_def_cnt;
1165 category_t **categories;
1166 int cat_def_cnt;
1167 } obj_symtab_data_t;
1168
1169 static void
emit_symtab_ref_cnt(def_t * def,void * data,int index)1170 emit_symtab_ref_cnt (def_t *def, void *data, int index)
1171 {
1172 obj_symtab_data_t *da = (obj_symtab_data_t *)data;
1173
1174 if (def->type != &type_integer)
1175 internal_error (0, "%s: expected integer def", __FUNCTION__);
1176 D_INT (def) = 0;
1177 if (da->refs)
1178 D_INT (def) = da->refs->type->t.array.size;
1179 }
1180
1181 static void
emit_symtab_refs(def_t * def,void * data,int index)1182 emit_symtab_refs (def_t *def, void *data, int index)
1183 {
1184 obj_symtab_data_t *da = (obj_symtab_data_t *)data;
1185
1186 if (def->type != &type_SEL)
1187 internal_error (0, "%s: expected SEL def", __FUNCTION__);
1188 D_INT (def) = 0;
1189 if (da->refs)
1190 EMIT_DEF (def->space, D_INT (def), da->refs);
1191 }
1192
1193 static void
emit_symtab_cls_def_cnt(def_t * def,void * data,int index)1194 emit_symtab_cls_def_cnt (def_t *def, void *data, int index)
1195 {
1196 obj_symtab_data_t *da = (obj_symtab_data_t *)data;
1197
1198 if (def->type != &type_integer)
1199 internal_error (0, "%s: expected integer def", __FUNCTION__);
1200 D_INT (def) = da->cls_def_cnt;
1201 }
1202
1203 static void
emit_symtab_cat_def_cnt(def_t * def,void * data,int index)1204 emit_symtab_cat_def_cnt (def_t *def, void *data, int index)
1205 {
1206 obj_symtab_data_t *da = (obj_symtab_data_t *)data;
1207
1208 if (def->type != &type_integer)
1209 internal_error (0, "%s: expected integer def", __FUNCTION__);
1210 D_INT (def) = da->cat_def_cnt;
1211 }
1212
1213 static void
emit_symtab_defs(def_t * def,void * data,int index)1214 emit_symtab_defs (def_t *def, void *data, int index)
1215 {
1216 obj_symtab_data_t *da = (obj_symtab_data_t *)data;
1217
1218 if (!is_array (def->type) || def->type->t.array.type->type != ev_pointer)
1219 internal_error (0, "%s: expected array of pointers def", __FUNCTION__);
1220 if (index < 0 || index >= da->cls_def_cnt + da->cat_def_cnt)
1221 internal_error (0, "%s: out of bounds index: %d %d",
1222 __FUNCTION__, index,
1223 da->cls_def_cnt + da->cat_def_cnt);
1224
1225 if (index < da->cls_def_cnt) {
1226 class_t **cl;
1227 for (cl = da->classes; *cl; cl++)
1228 if ((*cl)->def && !(*cl)->def->external)
1229 if (!index--)
1230 break;
1231 EMIT_DEF (def->space, D_INT (def), (*cl)->def);
1232 } else {
1233 category_t **ca;
1234 index -= da->cls_def_cnt;
1235 for (ca = da->categories; *ca; ca++)
1236 if ((*ca)->def && !(*ca)->def->external)
1237 if (!index--)
1238 break;
1239 EMIT_DEF (def->space, D_INT (def), (*ca)->def);
1240 }
1241 }
1242
1243 void
class_finish_module(void)1244 class_finish_module (void)
1245 {
1246 static struct_def_t symtab_struct[] = {
1247 {"sel_ref_cnt", &type_integer, emit_symtab_ref_cnt},
1248 {"refs", &type_SEL, emit_symtab_refs},
1249 {"cls_def_cnt", &type_integer, emit_symtab_cls_def_cnt},
1250 {"cat_def_cnt", &type_integer, emit_symtab_cat_def_cnt},
1251 {"defs", 0, emit_symtab_defs},
1252 {0, 0}
1253 };
1254
1255 obj_symtab_data_t data = {0, 0, 0, 0, 0};
1256
1257 class_t **cl;
1258 category_t **ca;
1259 def_t *symtab_def;
1260 symbol_t *module_sym;
1261 pr_module_t *module;
1262 symbol_t *exec_class_sym;
1263 symbol_t *init_sym;
1264 expr_t *init_expr;
1265 storage_class_t save_storage;
1266
1267 data.refs = emit_selectors ();
1268 if (class_hash) {
1269 data.classes = (class_t **) Hash_GetList (class_hash);
1270 for (cl = data.classes; *cl; cl++)
1271 if ((*cl)->def && !(*cl)->def->external)
1272 data.cls_def_cnt++;
1273 }
1274 if (category_hash) {
1275 data.categories = (category_t **) Hash_GetList (category_hash);
1276 for (ca = data.categories; *ca; ca++)
1277 if ((*ca)->def && !(*ca)->def->external)
1278 data.cat_def_cnt++;
1279 }
1280 if (!data.refs && !data.cls_def_cnt && !data.cat_def_cnt)
1281 return;
1282 symtab_struct[4].type = array_type (&type_pointer,
1283 data.cls_def_cnt + data.cat_def_cnt);
1284 symtab_def = emit_structure ("_OBJ_SYMTAB", 's', symtab_struct, 0, &data,
1285 sc_static);
1286 free (data.classes);
1287 free (data.categories);
1288
1289 module_sym = make_symbol ("_OBJ_MODULE", &type_obj_module, pr.far_data,
1290 sc_static);
1291 symtab_addsymbol (current_symtab, module_sym);
1292 module = &D_STRUCT (pr_module_t, module_sym->s.def);
1293 module->size = type_size (&type_obj_module);
1294 EMIT_STRING (module_sym->s.def->space, module->name,
1295 GETSTR (pr.source_file));
1296 EMIT_DEF (module_sym->s.def->space, module->symtab, symtab_def);
1297
1298 exec_class_sym = symtab_lookup (pr.symtab, "__obj_exec_class");
1299 if (!exec_class_sym) {
1300 exec_class_sym = new_symbol_type ("__obj_exec_class",
1301 &type_obj_exec_class);
1302 exec_class_sym = function_symbol (exec_class_sym, 0, 1);
1303 make_function (exec_class_sym, 0, exec_class_sym->table->space,
1304 sc_extern);
1305 }
1306
1307 init_sym = new_symbol_type (".ctor", &type_function);
1308 init_sym = function_symbol (init_sym, 0, 1);
1309
1310 init_expr = new_block_expr ();
1311 append_expr (init_expr,
1312 build_function_call (new_symbol_expr (exec_class_sym),
1313 exec_class_sym->type,
1314 address_expr (new_symbol_expr (module_sym),
1315 0, 0)));
1316
1317 save_storage = current_storage;
1318 current_storage = sc_static;
1319 current_func = begin_function (init_sym, 0, current_symtab, 1);
1320 build_code_function (init_sym, 0, init_expr);;
1321 current_func = 0;
1322 current_storage = save_storage;
1323 }
1324
1325 protocol_t *
get_protocol(const char * name,int create)1326 get_protocol (const char *name, int create)
1327 {
1328 protocol_t *p;
1329
1330 if (!protocol_hash)
1331 protocol_hash = Hash_NewTable (1021, protocol_get_key, 0, 0);
1332
1333 if (name) {
1334 p = Hash_Find (protocol_hash, name);
1335 if (p || !create)
1336 return p;
1337 }
1338
1339 p = calloc (sizeof (protocol_t), 1);
1340 p->name = name;
1341 p->methods = new_methodlist ();
1342 p->class_type.type = ct_protocol;
1343 p->class_type.c.protocol = p;
1344 if (name)
1345 Hash_Add (protocol_hash, p);
1346 return p;
1347 }
1348
1349 void
protocol_add_methods(protocol_t * protocol,methodlist_t * methods)1350 protocol_add_methods (protocol_t *protocol, methodlist_t *methods)
1351 {
1352 if (!methods)
1353 return;
1354 *protocol->methods->tail = methods->head;
1355 protocol->methods->tail = methods->tail;
1356 free (methods);
1357 }
1358
1359 void
protocol_add_protocols(protocol_t * protocol,protocollist_t * protocols)1360 protocol_add_protocols (protocol_t *protocol, protocollist_t *protocols)
1361 {
1362 protocol->protocols = protocols;
1363 }
1364
1365 def_t *
protocol_def(protocol_t * protocol)1366 protocol_def (protocol_t *protocol)
1367 {
1368 return make_symbol (protocol->name, &type_obj_protocol,
1369 pr.far_data, sc_static)->s.def;
1370 }
1371
1372 protocollist_t *
new_protocol_list(void)1373 new_protocol_list (void)
1374 {
1375 protocollist_t *protocollist = malloc (sizeof (protocollist_t));
1376
1377 protocollist->count = 0;
1378 protocollist->list = 0;
1379 return protocollist;
1380 }
1381
1382 protocollist_t *
add_protocol(protocollist_t * protocollist,const char * name)1383 add_protocol (protocollist_t *protocollist, const char *name)
1384 {
1385 protocol_t *protocol = get_protocol (name, 0);
1386
1387 if (!protocol) {
1388 error (0, "undefined protocol `%s'", name);
1389 return protocollist;
1390 }
1391 protocollist->count++;
1392 protocollist->list = realloc (protocollist->list,
1393 sizeof (protocol_t) * protocollist->count);
1394 protocollist->list[protocollist->count - 1] = protocol;
1395 return protocollist;
1396 }
1397
1398 int
procollist_find_protocol(protocollist_t * protocollist,protocol_t * proto)1399 procollist_find_protocol (protocollist_t *protocollist, protocol_t *proto)
1400 {
1401 int i;
1402 if (!protocollist)
1403 return 0;
1404 for (i = 0; i < protocollist->count; i++)
1405 if (protocollist->list[i] == proto)
1406 return 1;
1407 return 0;
1408 }
1409
1410 int
compare_protocols(protocollist_t * protos1,protocollist_t * protos2)1411 compare_protocols (protocollist_t *protos1, protocollist_t *protos2)
1412 {
1413 int i;
1414
1415 if (protos1 == protos2)
1416 return 1;
1417 if (!protos1 || !protos2)
1418 return 0;
1419 if (protos1->count != protos2->count)
1420 return 0;
1421 for (i = 0; i < protos1->count; i++)
1422 if (!procollist_find_protocol (protos2, protos1->list[i]))
1423 return 0;
1424 return 1;
1425 }
1426
1427 void
print_protocollist(dstring_t * dstr,protocollist_t * protocollist)1428 print_protocollist (dstring_t *dstr, protocollist_t *protocollist)
1429 {
1430 int i;
1431 dstring_appendstr (dstr, "<");
1432 for (i = 0; i < protocollist->count; i++)
1433 dasprintf (dstr, "%s%s", i ? "," : "", protocollist->list[i]->name);
1434 dstring_appendstr (dstr, ">");
1435 }
1436
1437 def_t *
emit_protocol(protocol_t * protocol)1438 emit_protocol (protocol_t *protocol)
1439 {
1440 def_t *proto_def;
1441 pr_protocol_t *proto;
1442 defspace_t *space;
1443
1444 proto_def = make_symbol (va ("_OBJ_PROTOCOL_%s", protocol->name),
1445 &type_obj_protocol, pr.far_data, sc_static)->s.def;
1446 if (proto_def->initialized)
1447 return proto_def;
1448 proto_def->initialized = proto_def->constant = 1;
1449 proto_def->nosave = 1;
1450 space = proto_def->space;
1451 proto = &D_STRUCT (pr_protocol_t, proto_def);
1452 proto->class_pointer = 0;
1453 EMIT_STRING (space, proto->protocol_name, protocol->name);
1454 EMIT_DEF (space, proto->protocol_list,
1455 emit_protocol_list (protocol->protocols,
1456 va ("PROTOCOL_%s", protocol->name)));
1457 EMIT_DEF (space, proto->instance_methods,
1458 emit_method_descriptions (protocol->methods, protocol->name, 1));
1459 EMIT_DEF (space, proto->class_methods,
1460 emit_method_descriptions (protocol->methods, protocol->name, 0));
1461 emit_class_ref ("Protocol");
1462 return proto_def;
1463 }
1464
1465 def_t *
emit_protocol_list(protocollist_t * protocols,const char * name)1466 emit_protocol_list (protocollist_t *protocols, const char *name)
1467 {
1468 //FIXME use emit_struct
1469 static struct_def_t proto_list_struct[] = {
1470 {"next", &type_pointer},
1471 {"count", &type_integer},
1472 {"list", 0}, // type will be filled in at run time
1473 {0, 0},
1474 };
1475 type_t *proto_list_type;
1476 def_t *proto_list_def;
1477 defspace_t *space;
1478 pr_protocol_list_t *proto_list;
1479 int i;
1480
1481 if (!protocols)
1482 return 0;
1483 proto_list_struct[2].type = array_type (&type_pointer, protocols->count);
1484 proto_list_type = make_structure (0, 's', proto_list_struct, 0)->type;
1485 proto_list_def = make_symbol (va ("_OBJ_PROTOCOLS_%s", name),
1486 proto_list_type,
1487 pr.far_data, sc_static)->s.def;
1488 proto_list_def->initialized = proto_list_def->constant = 1;
1489 proto_list_def->nosave = 1;
1490 space = proto_list_def->space;
1491 proto_list = &D_STRUCT (pr_protocol_list_t, proto_list_def);
1492 proto_list->next = 0;
1493 proto_list->count = protocols->count;
1494 for (i = 0; i < protocols->count; i++)
1495 EMIT_DEF (space, proto_list->list[i],
1496 emit_protocol (protocols->list[i]));
1497 return proto_list_def;
1498 }
1499
1500 void
clear_classes(void)1501 clear_classes (void)
1502 {
1503 if (class_hash)
1504 Hash_FlushTable (class_hash);
1505 if (protocol_hash)
1506 Hash_FlushTable (protocol_hash);
1507 if (category_hash)
1508 Hash_FlushTable (category_hash);
1509 obj_initialized = 0;
1510 }
1511
1512 symtab_t *
class_to_struct(class_t * class,symtab_t * symtab)1513 class_to_struct (class_t *class, symtab_t *symtab)
1514 {
1515 symtab_t *parent = symtab->parent;
1516 symtab_t *ivars = class->ivars;
1517 symtab_t *ancestor;
1518
1519 if (!ivars)
1520 return symtab;
1521
1522 // disconnect the struct symbol table from the scope
1523 symtab->parent = 0;
1524 // find the ancestor of the ivars symbol table chain
1525 for (ancestor = ivars; ancestor->parent; ancestor = ancestor->parent)
1526 ;
1527 // connect the ivars symbol table chain to the struct symbol table
1528 ancestor->parent = symtab;
1529 // create a new struct symbol table from the ivars symbol table chain
1530 symtab = symtab_flat_copy (ivars, 0);
1531 // disconnect the ivars symbol table chain
1532 ancestor->parent = 0;
1533 // connect the new struct symbol table to the scope
1534 symtab->parent = parent;
1535 return symtab;
1536 }
1537
1538 symtab_t *
class_ivar_scope(class_type_t * class_type,symtab_t * parent)1539 class_ivar_scope (class_type_t *class_type, symtab_t *parent)
1540 {
1541 class_t *class = extract_class (class_type);
1542 if (!class->ivars)
1543 return 0;
1544 return symtab_flat_copy (class->ivars, parent);
1545 }
1546
1547 void
class_finish_ivar_scope(class_type_t * class_type,symtab_t * ivar_scope,symtab_t * param_scope)1548 class_finish_ivar_scope (class_type_t *class_type, symtab_t *ivar_scope,
1549 symtab_t *param_scope)
1550 {
1551 class_t *class = extract_class (class_type);
1552 type_t *class_ptr = pointer_type (class->type);
1553 symbol_t *sym;
1554 symbol_t *self;
1555 expr_t *self_expr;
1556
1557 if (!ivar_scope)
1558 return;
1559 self = symtab_lookup (param_scope, "self");
1560 if (!self)
1561 internal_error (0, "I've lost my self!");
1562 self_expr = new_symbol_expr (self);
1563 if (self->type != class_ptr) {
1564 debug (0, "class method scope");
1565 //FIXME should generate a warning on access
1566 self_expr = cast_expr (class_ptr, self_expr);
1567 }
1568 for (sym = ivar_scope->symbols; sym; sym = sym->next) {
1569 if (sym->sy_type != sy_var)
1570 continue;
1571 sym->sy_type = sy_expr;
1572 sym->s.expr = binary_expr ('.', copy_expr (self_expr),
1573 new_symbol_expr (new_symbol (sym->name)));
1574 }
1575 }
1576
1577 static void
init_objective_structs(void)1578 init_objective_structs (void)
1579 {
1580 make_structure ("obj_selector", 's', sel_struct, &type_obj_selector);
1581 chain_type (&type_obj_selector);
1582 chain_type (&type_SEL);
1583 chain_type (&type_IMP);
1584
1585 make_structure ("obj_method", 's', method_struct, &type_obj_method);
1586 chain_type (&type_obj_method);
1587
1588 make_structure ("obj_method_description", 's', method_desc_struct,
1589 &type_obj_method_description);
1590 chain_type (&type_obj_method_description);
1591
1592 make_structure ("obj_category", 's', category_struct, &type_obj_category);
1593 chain_type (&type_obj_category);
1594
1595 make_structure ("obj_ivar", 's', ivar_struct, &type_obj_ivar);
1596 chain_type (&type_obj_ivar);
1597
1598 make_structure ("obj_super", 's', super_struct, &type_obj_super);
1599 chain_type (&type_obj_super);
1600 chain_type (&type_SuperPtr);
1601 chain_type (&type_supermsg);
1602
1603 symtab_addsymbol (current_symtab, new_symbol ("id"));
1604 }
1605
1606 static void
init_classes(void)1607 init_classes (void)
1608 {
1609 make_structure ("obj_class", 's', class_struct, &type_obj_class);
1610 chain_type (&type_obj_class);
1611 chain_type (&type_Class);
1612 make_structure ("obj_object", 's', object_struct, &type_obj_object);
1613 chain_type (&type_obj_object);
1614 chain_type (&type_id);
1615 make_structure ("obj_protocol", 's', protocol_struct, &type_obj_protocol);
1616 chain_type (&type_obj_protocol);
1617 }
1618
1619 static void
class_init_obj_module(void)1620 class_init_obj_module (void)
1621 {
1622 make_structure ("obj_module", 's', module_struct, &type_obj_module);
1623
1624 chain_type (&type_obj_module);
1625 chain_type (&type_moduleptr);
1626 chain_type (&type_obj_exec_class);
1627 }
1628
1629 void
class_init(void)1630 class_init (void)
1631 {
1632 symtab_t *cs = current_symtab;
1633
1634 current_symtab = pr.symtab;
1635 class_init_obj_module ();
1636 init_classes ();
1637 init_objective_structs ();
1638 obj_initialized = 1;
1639
1640 current_symtab = cs;
1641 }
1642