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.
This commit is contained in:
Bill Currie 2011-02-15 10:48:05 +09:00
parent 6bd63f811f
commit b2d4aee61e
3 changed files with 23 additions and 10 deletions

View file

@ -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)

View file

@ -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 *

View file

@ -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);
}