mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-22 02:11:19 +00:00
it seems object info emition works (needs more testing)
This commit is contained in:
parent
4cb3a5087b
commit
73f4cb4c03
12 changed files with 344 additions and 48 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue