it seems object info emition works (needs more testing)

This commit is contained in:
Bill Currie 2002-05-15 23:24:19 +00:00
parent 4cb3a5087b
commit 73f4cb4c03
12 changed files with 344 additions and 48 deletions

View file

@ -40,8 +40,10 @@ typedef struct class_s {
struct type_s *ivars;
struct methodlist_s *methods;
struct protocollist_s *protocols;
struct def_s *def;
} class_t;
struct method_s;
struct protocol_s;
struct type_s;
@ -50,6 +52,8 @@ void class_add_methods (class_t *class, struct methodlist_s *methods);
void class_add_protocol_methods (class_t *class, expr_t *protocols);
void class_add_protocol (class_t *class, struct protocol_s *protocol);
void class_check_ivars (class_t *class, struct type_s *ivars);
void class_finish (class_t *class);
struct method_s *class_find_method (class_t *class, struct method_s *method);
struct def_s *class_def (class_t *class);
class_t *get_category (const char *class_name, const char *category_name,
int create);
@ -57,6 +61,7 @@ class_t *get_category (const char *class_name, const char *category_name,
typedef struct protocol_s {
const char *name;
struct methodlist_s *methods;
struct protocollist_s *protocols;
} protocol_t;
typedef struct protocollist_s {
@ -71,4 +76,7 @@ struct def_s *protocol_def (protocol_t *protocol);
protocollist_t *new_protocollist (void);
void add_protocol (protocollist_t *protocollist, protocol_t *protocol);
int emit_protocol (protocol_t *protocol);
int emit_protocol_list (protocollist_t *protocols, const char *name);
#endif//__class_h

View file

@ -66,6 +66,7 @@ def_t *method_def (struct class_s *class, method_t *method);
methodlist_t *new_methodlist (void);
void copy_methods (methodlist_t *dst, methodlist_t *src);
int method_compare (method_t *m1, method_t *m2);
keywordarg_t *new_keywordarg (const char *selector, struct expr_s *expr);
@ -75,4 +76,6 @@ void selector_name (struct dstring_s *sel_id, keywordarg_t *selector);
void selector_types (struct dstring_s *sel_types, keywordarg_t *selector);
struct def_s *selector_def (const char *sel_id, const char *sel_types);
int emit_methods (methodlist_t *methods, const char *name, int instance);
#endif//__method_h

View file

@ -419,7 +419,6 @@ extern int pr_source_line;
extern def_t *pr_scope;
extern int pr_error_count;
int PR_GetTypeSize (type_t *type);
def_t *PR_GetArray (type_t *etype, const char *name, int size, def_t *scope,
int *allocate);
@ -439,6 +438,7 @@ void PR_DefInitialized (def_t *d);
#define G_VECTOR(o) (&pr_globals[o])
#define G_STRING(o) (strings + *(string_t *)&pr_globals[o])
#define G_FUNCTION(o) (*(func_t *)&pr_globals[o])
#define G_STRUCT(t,o) (*(t *)&pr_globals[o])
extern string_t s_file; // filename for function definition

View file

@ -54,6 +54,8 @@ struct type_s *new_struct (const char *name);
struct type_s *find_struct (const char *name);
void copy_struct_fields (struct type_s *dst, struct type_s *src);
int emit_struct (struct type_s *strct, const char *name);
void process_enum (struct expr_s *enm);
expr_t *get_enum (const char *name);

View file

@ -51,8 +51,9 @@ extern type_t type_Class;
extern type_t type_Protocol;
extern type_t type_SEL;
extern type_t type_IMP;
extern type_t type_method_list;
extern type_t *type_method;
extern type_t *type_category;
extern type_t *type_ivar;
extern def_t def_void;
extern def_t def_function;
@ -65,6 +66,7 @@ type_t *get_typedef (const char *name);
type_t *pointer_type (type_t *aux);
void print_type (type_t *type);
void encode_type (struct dstring_s *encodking, type_t *type);
int type_size (type_t *type);
void init_types (void);

View file

@ -32,6 +32,8 @@ static const char rcsid[] =
#include "QF/dstring.h"
#include "QF/hash.h"
#include "QF/pr_obj.h"
#include "QF/va.h"
#include "qfcc.h"
@ -116,6 +118,71 @@ class_add_protocol (class_t *class, protocol_t *protocol)
add_protocol (class->protocols, protocol);
}
void
class_finish (class_t *class)
{
if (class->def)
return;
if (class->class_name && class->category_name) {
def_t *category_def;
pr_category_t *category;
category_def = PR_GetDef (type_category,
va ("_OBJ_CATEGORY_%s_%s",
class->class_name,
class->category_name),
0, &numpr_globals);
category = &G_STRUCT (pr_category_t, category_def->ofs);
} else if (class->class_name) {
def_t *meta_def;
pr_class_t *meta;
pr_class_t *cls;
meta_def = PR_GetDef (type_Class.aux_type,
va ("_OBJ_METACLASS_%s", class->class_name),
0, &numpr_globals);
meta = &G_STRUCT (pr_class_t, meta_def->ofs);
memset (meta, 0, sizeof (*meta));
meta->class_pointer = ReuseString (class->class_name);
meta->name = meta->class_pointer;
meta->instance_size = type_size (type_Class.aux_type);
meta->ivars = emit_struct (type_Class.aux_type, "Class");
meta->methods = emit_methods (class->methods, class->class_name, 0);
meta->protocols = emit_protocol_list (class->protocols,
class->class_name);
class->def = PR_GetDef (type_Class.aux_type,
va ("_OBJ_METACLASS_%s", class->class_name),
0, &numpr_globals);
cls = &G_STRUCT (pr_class_t, class->def->ofs);
cls->class_pointer = meta_def->ofs;
if (class->super_class)
cls->super_class = class->super_class->def->ofs;
cls->name = meta->name;
cls->instance_size = type_size (class->ivars);
cls->ivars = emit_struct (class->ivars, class->class_name);
cls->methods = emit_methods (class->methods, class->class_name, 1);
cls->protocols = meta->protocols;
}
}
method_t *
class_find_method (class_t *class, method_t *method)
{
method_t *m;
dstring_t *sel;
for (m = class->methods->head; m; m = m->next)
if (method_compare (method, m))
return m;
sel = dstring_newstr ();
selector_name (sel, (keywordarg_t *)method->selector);
warning (0, "method %s not in %s%s", sel->str, class->class_name,
class->category_name ? va (" (%s)", class->category_name) : "");
dstring_delete (sel);
return method;
}
static unsigned long
category_get_hash (void *_c, void *unused)
{
@ -244,3 +311,50 @@ add_protocol (protocollist_t *protocollist, protocol_t *protocol)
* sizeof (protocollist_t));
protocollist->list[protocollist->count++] = protocol;
}
int
emit_protocol (protocol_t *protocol)
{
def_t *proto_def;
pr_protocol_t *proto;
proto_def = PR_GetDef (type_Protocol.aux_type,
va ("_OBJ_PROTOCOL_%s", protocol->name),
0, &numpr_globals);
proto = &G_STRUCT (pr_protocol_t, proto_def->ofs);
proto->class_pointer = 0;
proto->protocol_name = ReuseString (protocol->name);
proto->protocol_list =
emit_protocol_list (protocol->protocols,
va ("PROTOCOL_%s", protocol->name));
proto->instance_methods = emit_methods (protocol->methods,
protocol->name, 1);
proto->class_methods = emit_methods (protocol->methods, protocol->name, 0);
return proto_def->ofs;
}
int
emit_protocol_list (protocollist_t *protocols, const char *name)
{
def_t *proto_list_def;
type_t *protocol_list;
pr_protocol_list_t *proto_list;
int i;
if (!protocols)
return 0;
protocol_list = new_struct (0);
new_struct_field (protocol_list, &type_pointer, "next", vis_public);
new_struct_field (protocol_list, &type_integer, "count", vis_public);
for (i = 0; i < protocols->count; i++)
new_struct_field (protocol_list, &type_pointer, 0, vis_public);
proto_list_def = PR_GetDef (type_Protocol.aux_type,
va ("_OBJ_PROTOCOLS_%s", name),
0, &numpr_globals);
proto_list = &G_STRUCT (pr_protocol_list_t, proto_list_def->ofs);
proto_list->next = 0;
proto_list->count = protocols->count;
for (i = 0; i < protocols->count; i++)
proto_list->list[i] = emit_protocol (protocols->list[i]);
return proto_list_def->ofs;
}

View file

@ -1693,7 +1693,7 @@ array_expr (expr_t *array, expr_t *index)
&& index->type >= ex_integer
&& index->e.uinteger_val >= array_type->num_parms)
return error (index, "array index out of bounds");
size = PR_GetTypeSize (array_type->aux_type);
size = type_size (array_type->aux_type);
if (size > 1) {
scale = new_expr ();
scale->type = expr_types[index_type->type];

View file

@ -32,11 +32,14 @@ static const char rcsid[] =
#include "QF/dstring.h"
#include "QF/hash.h"
#include "QF/pr_obj.h"
#include "QF/va.h"
#include "qfcc.h"
#include "class.h"
#include "method.h"
#include "struct.h"
#include "type.h"
static def_t *send_message_def;
@ -123,6 +126,31 @@ copy_methods (methodlist_t *dst, methodlist_t *src)
}
}
int
method_compare (method_t *m1, method_t *m2)
{
dstring_t *s1 = dstring_newstr ();
dstring_t *s2 = dstring_newstr ();
dstring_t *t1 = dstring_newstr ();
dstring_t *t2 = dstring_newstr ();
int res;
selector_name (s1, (keywordarg_t *)m1->selector);
selector_name (s2, (keywordarg_t *)m2->selector);
selector_types (t1, (keywordarg_t *)m1->selector);
selector_types (t2, (keywordarg_t *)m2->selector);
res = strcmp (s1->str, s2->str) == 0
&& strcmp (t1->str, t2->str) == 0;
dstring_delete (s1);
dstring_delete (s2);
dstring_delete (t1);
dstring_delete (t2);
return res;
}
keywordarg_t *
new_keywordarg (const char *selector, struct expr_s *expr)
{
@ -168,6 +196,7 @@ selector_name (dstring_t *sel_id, keywordarg_t *selector)
void
selector_types (dstring_t *sel_types, keywordarg_t *selector)
{
dstring_clearstr (sel_types);
}
typedef struct {
@ -228,3 +257,42 @@ selector_def (const char *_sel_id, const char *_sel_types)
Hash_AddElement (sel_def_hash, sel_def);
return sel_def->def;
}
int
emit_methods (methodlist_t *_methods, const char *name, int instance)
{
const char *type = instance ? "INSTANCE" : "CLASS";
method_t *method;
int i, count;
def_t *methods_def;
pr_method_list_t *methods;
type_t *method_list;
dstring_t *tmp = dstring_newstr ();
for (count = 0, method = _methods->head; method; method = method->next)
if (!method->instance == !instance)
count++;
method_list = new_struct (0);
new_struct_field (method_list, &type_pointer, "method_next", vis_public);
new_struct_field (method_list, &type_integer, "method_count", vis_public);
for (i = 0; i < count; i++)
new_struct_field (method_list, type_method, 0, vis_public);
methods_def = PR_GetDef (method_list, va ("_OBJ_%s_METHODS_%s", type, name),
0, &numpr_globals);
methods = &G_STRUCT (pr_method_list_t, methods_def->ofs);
methods->method_next = 0;
methods->method_count = count;
for (i = 0, method = _methods->head; method; method = method->next) {
if (!method->instance != !instance)
continue;
selector_name (tmp, (keywordarg_t *)method->selector);
methods->method_list[i].method_name.sel_id = ReuseString (tmp->str);
selector_name (tmp, (keywordarg_t *)method->selector);
methods->method_list[i].method_name.sel_types = ReuseString (tmp->str);
methods->method_list[i].method_types =
methods->method_list[i].method_name.sel_types;
methods->method_list[i].method_imp = method->def->ofs;
}
dstring_delete (tmp);
return methods_def->ofs;
}

View file

@ -93,20 +93,12 @@ PR_GetArray (type_t *etype, const char *name, int size, def_t *scope,
def = PR_NewDef (type, name, scope);
def->ofs = *allocate;
def->initialized = def->constant = 1;
*allocate += pr_type_size[type->type] * size + 1;
*allocate += type_size (type) * size + 1;
pr_global_defs[def->ofs] = def;
G_INT (def->ofs) = def->ofs + 1;
return def;
}
int
PR_GetTypeSize (type_t *type)
{
if (type->type == ev_struct)
return type->num_parms;
return pr_type_size[type->type];
}
/*
PR_GetDef
@ -153,7 +145,7 @@ PR_GetDef (type_t *type, const char *name, def_t *scope, int *allocate)
d->used = 1;
d->parent = def;
} else {
*allocate += PR_GetTypeSize(type);
*allocate += type_size (type);
}
if (type->type == ev_field) {
@ -178,16 +170,16 @@ PR_GetDef (type_t *type, const char *name, def_t *scope, int *allocate)
d->parent = def;
} else if (type->aux_type->type == ev_pointer) {
//FIXME I don't think this is right for a field pointer
size = PR_GetTypeSize (type->aux_type->aux_type);
size = type_size (type->aux_type->aux_type);
pr.size_fields += type->aux_type->num_parms * size;
} else {
size = PR_GetTypeSize (type->aux_type);
size = type_size (type->aux_type);
pr.size_fields += size;
}
} else if (type->type == ev_pointer && type->num_parms) {
int ofs = *allocate;
size = PR_GetTypeSize (type->aux_type);
size = type_size (type->aux_type);
*allocate += type->num_parms * size;
if (pr_scope) {

View file

@ -869,6 +869,8 @@ obj_def
{
if (!current_class)
PARSE_ERROR;
else
class_finish (current_class);
current_class = 0;
}
;
@ -1060,41 +1062,47 @@ ivar_declarator
;
methoddef
: '+'
methoddecl opt_state_expr
: '+' methoddecl
{
$2->instance = 0;
$2 = class_find_method (current_class, $2);
}
opt_state_expr
{
current_def = $2->def = method_def (current_class, $2);
current_params = $2->params;
}
begin_function statement_block end_function
{
build_function ($5);
if ($3) {
$3->next = $6;
emit_function ($5, $3);
build_function ($6);
if ($4) {
$4->next = $7;
emit_function ($6, $4);
} else {
emit_function ($5, $6);
emit_function ($6, $7);
}
finish_function ($5);
finish_function ($6);
}
| '-'
methoddecl opt_state_expr
| '-' methoddecl
{
$2->instance = 1;
$2 = class_find_method (current_class, $2);
}
opt_state_expr
{
current_def = $2->def = method_def (current_class, $2);
current_params = $2->params;
}
begin_function statement_block end_function
{
build_function ($5);
if ($3) {
$3->next = $6;
emit_function ($5, $3);
build_function ($6);
if ($4) {
$4->next = $7;
emit_function ($6, $4);
} else {
emit_function ($5, $6);
emit_function ($6, $7);
}
finish_function ($5);
finish_function ($6);
}
;

View file

@ -30,11 +30,15 @@
static const char rcsid[] =
"$Id$";
#include <QF/dstring.h>
#include <QF/hash.h>
#include <QF/pr_obj.h>
#include <QF/sys.h>
#include <QF/va.h>
#include "qfcc.h"
#include "struct.h"
#include "type.h"
typedef struct {
const char *name;
@ -80,11 +84,12 @@ new_struct_field (type_t *strct, type_t *type, const char *name,
field->name = name;
field->type = type;
field->offset = strct->num_parms;
strct->num_parms += pr_type_size[type->type];
strct->num_parms += type_size (type);
field->next = 0;
*strct->struct_tail = field;
strct->struct_tail = &field->next;
Hash_Add (strct->struct_fields, field);
if (name)
Hash_Add (strct->struct_fields, field);
return field;
}
@ -162,6 +167,37 @@ struct_compare_fields (struct type_s *s1, struct type_s *s2)
return !((!f1) ^ !(f2));
}
int
emit_struct(type_t *strct, const char *name)
{
struct_field_t *field;
int i, count;
def_t *ivars_def;
pr_ivar_list_t *ivars;
type_t *ivar_list;
dstring_t *encoding = dstring_newstr ();
for (count = 0, field = strct->struct_head; field; field = field->next)
count++;
ivar_list = new_struct (0);
new_struct_field (ivar_list, &type_integer, "ivar_count", vis_public);
for (i = 0; i < count; i++)
new_struct_field (ivar_list, type_ivar, 0, vis_public);
ivars_def = PR_GetDef (ivar_list, va ("_OBJ_INSTANCE_VARIABLES_%s", name),
0, &numpr_globals);
ivars = &G_STRUCT (pr_ivar_list_t, ivars_def->ofs);
ivars->ivar_count = count;
for (i = 0, field = strct->struct_head; field; i++, field = field->next) {
encode_type (encoding, field->type);
ivars->ivar_list[i].ivar_name = ReuseString (field->name);
ivars->ivar_list[i].ivar_type = ReuseString (encoding->str);
ivars->ivar_list[i].ivar_offset = field->offset;
dstring_clearstr (encoding);
}
dstring_delete (encoding);
return ivars_def->ofs;
}
void
process_enum (expr_t *enm)
{

View file

@ -39,6 +39,7 @@ static const char rcsid[] =
#include "qfcc.h"
#include "function.h"
#include "struct.h"
#include "type.h"
typedef struct {
const char *name;
@ -55,7 +56,7 @@ type_t type_field = { ev_field };
// type_function is a void() function used for state defs
type_t type_function = { ev_func, NULL, &type_void };
type_t type_pointer = { ev_pointer };
type_t type_pointer = { ev_pointer, NULL, &type_void };
type_t type_quaternion = { ev_quaternion };
type_t type_integer = { ev_integer };
type_t type_uinteger = { ev_uinteger };
@ -67,8 +68,9 @@ type_t type_Class = { ev_pointer };
type_t type_Protocol = { ev_pointer };
type_t type_SEL = { ev_pointer };
type_t type_IMP = { ev_func, NULL, &type_id, -3, { &type_id, &type_SEL }};
type_t type_method_list = { ev_pointer };
type_t *type_method;
type_t *type_category;
type_t *type_ivar;
type_t type_floatfield = { ev_field, NULL, &type_float };
@ -295,9 +297,11 @@ _encode_type (dstring_t *encoding, type_t *type, int level)
case ev_class:
dstring_appendstr (encoding, "{");
//XXX dstring_appendstr (encoding, name);
dstring_appendstr (encoding, "=");
for (field = type->struct_head; field; field = field->next)
_encode_type (encoding, field->type, level + 1);
if (level < 2) {
dstring_appendstr (encoding, "=");
for (field = type->struct_head; field; field = field->next)
_encode_type (encoding, field->type, level + 1);
}
dstring_appendstr (encoding, "}");
break;
case ev_sel:
@ -315,6 +319,42 @@ encode_type (dstring_t *encoding, type_t *type)
_encode_type (encoding, type, 0);
}
int
type_size (type_t *type)
{
struct_field_t *field;
int size;
if (!type)
return 0;
switch (type->type) {
case ev_void:
case ev_string:
case ev_float:
case ev_vector:
case ev_entity:
case ev_field:
case ev_func:
case ev_pointer:
case ev_quaternion:
case ev_integer:
case ev_uinteger:
case ev_short:
case ev_sel:
case ev_type_count:
return pr_type_size[type->type];
case ev_struct:
case ev_object:
case ev_class:
for (size = 0, field = type->struct_head;
field;
field = field->next)
size += type_size (field->type);
return size;
}
return 0;
}
void
init_types (void)
{
@ -341,28 +381,51 @@ init_types (void)
new_struct_field (type, &type_string, "sel_types", vis_public);
chain_type (&type_SEL);
type_method = new_struct ("obj_method");
type_method = new_struct (0);
new_struct_field (type_method, &type_SEL, "method_name", vis_public);
new_struct_field (type_method, &type_string, "method_types", vis_public);
new_struct_field (type_method, &type_IMP, "method_imp", vis_public);
chain_type (type_method);
type = type_method_list.aux_type = new_struct ("obj_method_list");
new_struct_field (type, &type_method_list, "method_next", vis_public);
new_struct_field (type, &type_integer, "method_count", vis_public);
new_struct_field (type, array_type (type_method, 1),
"method_list", vis_public);
chain_type (&type_method_list);
type = type_Class.aux_type = new_struct ("Class");
new_struct_field (type, &type_Class, "class_pointer", vis_public);
new_struct_field (type, &type_Class, "super_class", vis_public);
new_struct_field (type, &type_Class, "methods", vis_public);
new_struct_field (type, &type_string, "name", vis_public);
new_struct_field (type, &type_integer, "version", vis_public);
new_struct_field (type, &type_integer, "info", vis_public);
new_struct_field (type, &type_integer, "instance_size", vis_public);
new_struct_field (type, &type_pointer, "ivars", vis_public);
new_struct_field (type, &type_pointer, "methods", vis_public);
new_struct_field (type, &type_pointer, "dtable", vis_public);
new_struct_field (type, &type_pointer, "subclass_list", vis_public);
new_struct_field (type, &type_pointer, "sibling_class", vis_public);
new_struct_field (type, &type_pointer, "protocols", vis_public);
new_struct_field (type, &type_pointer, "gc_object_type", vis_public);
chain_type (&type_Class);
type = type_Protocol.aux_type = new_struct ("Protocol");
new_struct_field (type, &type_Class, "class_pointer", vis_public);
new_struct_field (type, &type_string, "protocol_name", vis_public);
new_struct_field (type, &type_pointer, "protocol_list", vis_public);
new_struct_field (type, &type_pointer, "instance_methods", vis_public);
new_struct_field (type, &type_pointer, "class_methods", vis_public);
chain_type (&type_Protocol);
type = type_id.aux_type = new_struct ("id");
new_struct_field (type, &type_Class, "class_pointer", vis_public);
chain_type (&type_id);
type = type_category = new_struct (0);
new_struct_field (type, &type_string, "category_name", vis_public);
new_struct_field (type, &type_string, "class_name", vis_public);
new_struct_field (type, &type_pointer, "instance_methods", vis_public);
new_struct_field (type, &type_pointer, "class_methods", vis_public);
new_struct_field (type, &type_pointer, "protocols", vis_public);
chain_type (type_category);
type = type_ivar = new_struct (0);
new_struct_field (type, &type_string, "ivar_name", vis_public);
new_struct_field (type, &type_string, "ivar_type", vis_public);
new_struct_field (type, &type_integer, "ivar_offset", vis_public);
chain_type (type_ivar);
}