write out the module data needed for the obj runtime

This commit is contained in:
Bill Currie 2002-05-21 21:28:40 +00:00
parent a8c3fa8ffc
commit 9f06f89d57
10 changed files with 152 additions and 11 deletions

View file

@ -145,4 +145,19 @@ typedef struct pr_ivar_list_s {
} pr_ivar_list_t;
typedef struct pr_ivar_s pr_ivar_t;
typedef struct pr_symtab_s {
int sel_ref_cnt;
int cls_def_cnt;
int cat_def_cnt;
pointer_t defs[1]; // variable array of class pointers then
// category pointers
} pr_symtab_t;
typedef struct pr_module_s {
int version;
int size;
string_t name;
pointer_t symtab; // pr_symtab_t
} pr_module_t;
#endif//__pr_obj_h

View file

@ -71,6 +71,7 @@ struct method_s *class_message_response (class_t *class, struct expr_s *sel);
struct def_s *class_def (class_t *class);
class_t *get_category (const char *class_name, const char *category_name,
int create);
void class_finish_module (void);
typedef struct protocol_s {
const char *name;

View file

@ -415,6 +415,7 @@ extern def_t *pr_global_defs[MAX_REGS]; // to find def for a global
def_t *PR_ReuseConstant (expr_t *expr, def_t *def);
extern char destfile[];
extern int pr_source_line;
extern def_t *pr_scope;

View file

@ -51,9 +51,11 @@ extern type_t type_Class;
extern type_t type_Protocol;
extern type_t type_SEL;
extern type_t type_IMP;
extern type_t type_obj_exec_class;
extern type_t *type_method;
extern type_t *type_category;
extern type_t *type_ivar;
extern type_t *type_module;
extern def_t def_void;
extern def_t def_function;

View file

@ -134,14 +134,21 @@ class_begin (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_def->initialized = category_def->constant = 1;
class->def = PR_GetDef (type_category,
va ("_OBJ_CATEGORY_%s_%s",
class->class_name,
class->category_name),
0, &numpr_globals);
class->def->initialized = class->def->constant = 1;
category = &G_STRUCT (pr_category_t, class->def->ofs);
category->category_name = ReuseString (class->category_name);
category->class_name = ReuseString (class->class_name);
category->protocols = emit_protocol_list (class->protocols,
va ("%s_%s",
class->class_name,
class->category_name));
} else if (class->class_name) {
def_t *meta_def;
pr_class_t *meta;
@ -182,6 +189,16 @@ class_finish (class_t *class)
pr_category_t *category;
category = &G_STRUCT (pr_category_t, class->def->ofs);
category->instance_methods = emit_methods (class->methods,
va ("%s_%s",
class->class_name,
class->category_name),
1);
category->class_methods = emit_methods (class->methods,
va ("%s_%s",
class->class_name,
class->category_name),
0);
} else if (class->class_name) {
pr_class_t *meta;
pr_class_t *cls;
@ -347,7 +364,7 @@ get_category (const char *class_name, const char *category_name, int create)
c = calloc (sizeof (class_t), 1);
c->class_name = class_name;
c->class_name = category_name;
c->category_name = category_name;
if (class_name && category_name)
Hash_AddElement (category_hash, c);
return c;
@ -372,6 +389,88 @@ class_def (class_t *class)
return def;
}
void
class_finish_module (void)
{
class_t **classes = 0;
class_t **categories = 0;
class_t **t;
int num_classes = 0;
int num_categories = 0;
int i;
type_t *symtab_type;
def_t *symtab_def;
pr_symtab_t *symtab;
pointer_t *def_ptr;
def_t *module_def;
pr_module_t *module;
def_t *exec_class_def;
function_t *exec_class_func;
def_t *init_def;
function_t *init_func;
expr_t *init_expr;
if (class_hash) {
classes = (class_t **) Hash_GetList (class_hash);
for (t = classes; *t; t++)
if ((*t)->def)
num_classes++;
}
if (category_hash) {
categories = (class_t **) Hash_GetList (category_hash);
for (t = categories; *t; t++)
if ((*t)->def)
num_categories++;
}
if (!num_classes && !num_categories)
return;
symtab_type = new_struct (0);
new_struct_field (symtab_type, &type_integer, "sel_ref_cnt", vis_public);
new_struct_field (symtab_type, &type_integer, "cls_def_cnt", vis_public);
new_struct_field (symtab_type, &type_integer, "cat_def_cnt", vis_public);
for (i = 0; i < num_classes + num_categories; i++)
new_struct_field (symtab_type, &type_pointer, 0, vis_public);
symtab_def = PR_GetDef (symtab_type, "_OBJ_SYMTAB", 0, &numpr_globals);
symtab_def->initialized = symtab_def->constant = 1;
symtab = &G_STRUCT (pr_symtab_t, symtab_def->ofs);
symtab->cls_def_cnt = num_classes;
symtab->cat_def_cnt = num_categories;
def_ptr = symtab->defs;
for (i = 0, t = classes; i < num_classes; i++, t++)
if ((*t)->def)
*def_ptr++ = (*t)->def->ofs;
for (i = 0, t = categories; i < num_categories; i++, t++)
if ((*t)->def)
*def_ptr++ = (*t)->def->ofs;
module_def = PR_GetDef (type_module, "_OBJ_MODULE", 0, &numpr_globals);
module_def->initialized = module_def->constant = 1;
module = &G_STRUCT (pr_module_t, module_def->ofs);
module->size = type_size (type_module);
module->name = ReuseString (destfile);
module->symtab = symtab_def->ofs;
exec_class_def = PR_GetDef (&type_obj_exec_class, "__obj_exec_class",
0, &numpr_globals);
exec_class_func = new_function ();
exec_class_func->builtin = 0;
exec_class_func->def = exec_class_def;
build_function (exec_class_func);
finish_function (exec_class_func);
init_def = PR_GetDef (&type_function, ".ctor", 0, &numpr_globals);
init_func = new_function ();
init_func->def = init_def;
init_func->code = numstatements;
build_function (init_func);
init_expr = new_block_expr ();
append_expr (init_expr,
function_expr (new_def_expr (exec_class_def),
address_expr (new_def_expr (module_def), 0, 0)));
emit_function (init_func, init_expr);
finish_function (init_func);
}
protocol_t *
get_protocol (const char *name, int create)
{

View file

@ -85,6 +85,10 @@ type_t *types[] = {
&type_integer,
&type_uinteger,
&type_short,
&type_void, // FIXME what type?
&type_void, // FIXME what type?
&type_void, // FIXME what type?
&type_SEL,
};
expr_type expr_types[] = {

View file

@ -243,6 +243,7 @@ static keyword_t keywords[] = {
{"integer", TYPE, &type_integer, 0, PROG_VERSION},
{"function", TYPE, &type_function, 0, PROG_VERSION},
{"id", TYPE, &type_id, 0, PROG_VERSION},
{"Class", TYPE, &type_Class, 0, PROG_VERSION},
{"SEL", TYPE, &type_SEL, 0, PROG_VERSION},
{"IMP", TYPE, &type_IMP, 0, PROG_VERSION},
{"local", LOCAL, 0, 1, PROG_ID_VERSION},

View file

@ -63,6 +63,7 @@ static const char rcsid[] =
#include <QF/sys.h>
#include "qfcc.h"
#include "class.h"
#include "type.h"
options_t options;
@ -531,6 +532,7 @@ qboolean PR_FinishCompilation (void)
def_t *def;
expr_t e;
class_finish_module ();
// check to make sure all functions prototyped have code
if (options.warnings.undefined_function)
for (d = pr.def_head.def_next; d; d = d->def_next) {

View file

@ -181,7 +181,8 @@ emit_struct(type_t *strct, const char *name)
if (!strct)
return 0;
for (count = 0, field = strct->struct_head; field; field = field->next)
count++;
if (field->name)
count++;
ivar_list = new_struct (0);
new_struct_field (ivar_list, &type_integer, "ivar_count", vis_public);
for (i = 0; i < count; i++)
@ -194,12 +195,15 @@ emit_struct(type_t *strct, const char *name)
ivars_def->initialized = ivars_def->constant = 1;
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) {
for (i = 0, field = strct->struct_head; field; field = field->next) {
if (!field->name)
continue;
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);
i++;
}
done:
dstring_delete (encoding);

View file

@ -70,9 +70,11 @@ 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_obj_exec_class = { ev_func, NULL, &type_void, 1, { 0 }};
type_t *type_method;
type_t *type_category;
type_t *type_ivar;
type_t *type_module;
type_t type_floatfield = { ev_field, NULL, &type_float };
@ -428,7 +430,7 @@ init_types (void)
new_struct_field (type_method, &type_IMP, "method_imp", vis_public);
chain_type (type_method);
type = type_Class.aux_type = new_struct ("Class");
type = type_Class.aux_type = new_struct (0);
type->type = ev_class;
type->class = &class_Class;
class_Class.ivars = type_Class.aux_type;
@ -478,4 +480,14 @@ init_types (void)
new_struct_field (type, &type_string, "ivar_type", vis_public);
new_struct_field (type, &type_integer, "ivar_offset", vis_public);
chain_type (type_ivar);
type = type_module = new_struct (0);
new_struct_field (type, &type_integer, "version", vis_public);
new_struct_field (type, &type_integer, "size", vis_public);
new_struct_field (type, &type_string, "name", vis_public);
new_struct_field (type, &type_pointer, "symtab", vis_public);
chain_type (type_module);
type_obj_exec_class.parm_types[0] = pointer_type (type_module);
chain_type (&type_obj_exec_class);
}