mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-29 20:20:43 +00:00
write out the module data needed for the obj runtime
This commit is contained in:
parent
a8c3fa8ffc
commit
9f06f89d57
10 changed files with 152 additions and 11 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue