From b2d4aee61e561c9e45163aaa438730e265f8fe82 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 15 Feb 2011 10:48:05 +0900 Subject: [PATCH] Reimplement selector expressions to work with far data. They currently execute a lea instruction every method call, but the optimizer should take care of that once its written. --- tools/qfcc/source/class.c | 7 ++----- tools/qfcc/source/expr.c | 17 +++++++++++++---- tools/qfcc/source/method.c | 9 ++++++++- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/tools/qfcc/source/class.c b/tools/qfcc/source/class.c index 7f84429f8..5baacec08 100644 --- a/tools/qfcc/source/class.c +++ b/tools/qfcc/source/class.c @@ -835,12 +835,9 @@ class_message_response (class_t *class, int class_msg, expr_t *sel) class_t *c = class; category_t *cat; - if (sel->type != ex_value && sel->e.value.type != ev_pointer - && sel->e.value.v.pointer.type != type_SEL.t.fldptr.type) { - error (sel, "not a selector"); - return 0; - } selector = get_selector (sel); + if (!selector) + return 0; if (class->type == &type_id) { m = find_method (selector->name); if (m) diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index c9b151d16..73c20c200 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -2503,6 +2503,7 @@ selector_expr (keywordarg_t *selector) dstring_t *sel_id = dstring_newstr (); expr_t *sel; symbol_t *sel_sym; + symbol_t *sel_table; int index; selector = copy_keywordargs (selector); @@ -2510,13 +2511,21 @@ selector_expr (keywordarg_t *selector) selector_name (sel_id, selector); index = selector_index (sel_id->str); index *= type_size (type_SEL.t.fldptr.type); - sel_sym = make_symbol ("_OBJ_SELECTOR_TABLE", type_SEL.t.fldptr.type, - 0, st_extern); - if (!sel_sym->table) + sel_sym = make_symbol ("_OBJ_SELECTOR_TABLE_PTR", &type_SEL, + pr.near_data, st_static); + if (!sel_sym->table) { symtab_addsymbol (pr.symtab, sel_sym); + sel_table = make_symbol ("_OBJ_SELECTOR_TABLE", type_SEL.t.fldptr.type, + pr.far_data, st_extern); + if (!sel_table->table) + symtab_addsymbol (pr.symtab, sel_table); + reloc_def_def (sel_table->s.def, sel_sym->s.def); + } sel = new_symbol_expr (sel_sym); dstring_delete (sel_id); - return address_expr (sel, new_short_expr (index), 0); + sel = new_binary_expr ('&', sel, new_short_expr (index)); + sel->e.expr.type = &type_SEL; + return sel; } expr_t * diff --git a/tools/qfcc/source/method.c b/tools/qfcc/source/method.c index fc4a8a1c0..62d5f8451 100644 --- a/tools/qfcc/source/method.c +++ b/tools/qfcc/source/method.c @@ -365,7 +365,14 @@ selector_index (const char *sel_id) selector_t * get_selector (expr_t *sel) { - selector_t _sel = {0, 0, sel->e.value.v.pointer.val}; + selector_t _sel = {0, 0, 0}; + + if (sel->type != ex_expr && sel->e.expr.op != '&' + && sel->e.expr.type != &type_SEL) { + error (sel, "not a selector"); + return 0; + } + _sel.index = expr_short (sel->e.expr.e2); _sel.index /= type_size (type_SEL.t.fldptr.type); return (selector_t *) Hash_FindElement (sel_index_hash, &_sel); }