Emit pointers properly.

Rename ReuseConstant to emit_value and use emit_value to emit any non-short
constant. This fixes the null pointer in the call to __obj_exec_class.
This commit is contained in:
Bill Currie 2011-02-13 10:09:42 +09:00
parent 1bcf434b20
commit c4f364fd37
3 changed files with 18 additions and 31 deletions

View file

@ -32,8 +32,8 @@
#ifndef __immediate_h #ifndef __immediate_h
#define __immediate_h #define __immediate_h
struct expr_s; struct ex_value_s;
struct def_s *ReuseConstant (struct expr_s *expr, struct def_s *def); struct def_s *emit_value (struct ex_value_s *value, struct def_s *def);
int ReuseString (const char *str); int ReuseString (const char *str);

View file

@ -65,7 +65,6 @@ static def_t zero_def;
static def_t * static def_t *
get_value_def (ex_value_t *value, etype_t type) get_value_def (ex_value_t *value, etype_t type)
{ {
//FIXME share immediates
def_t *def; def_t *def;
if (type == ev_short) { if (type == ev_short) {
@ -73,14 +72,7 @@ get_value_def (ex_value_t *value, etype_t type)
def->offset = value->v.short_val; def->offset = value->v.short_val;
return def; return def;
} }
def = new_def (".imm", ev_types[type], pr.near_data, st_static); return emit_value (value, 0);
if (type == ev_string) {
EMIT_STRING (def->space, D_STRUCT (string_t, def),
value->v.string_val);
} else {
memcpy (D_POINTER (pr_type_t, def), &value->v, pr_type_size[type]);
}
return def;
} }
static def_t * static def_t *

View file

@ -156,23 +156,19 @@ ReuseString (const char *str)
} }
def_t * def_t *
ReuseConstant (expr_t *expr, def_t *def) emit_value (ex_value_t *value, def_t *def)
{ {
def_t *cn; def_t *cn;
hashtab_t *tab = 0; hashtab_t *tab = 0;
type_t *type; type_t *type;
expr_t e = *expr; ex_value_t val = *value;
immediate_t *imm, search; immediate_t *imm, search;
if (!string_imm_defs) { if (!string_imm_defs) {
clear_immediates (); clear_immediates ();
} }
cn = 0; cn = 0;
if (e.type == ex_nil) switch (val.type) {
convert_nil (&e, def->type);
if (!is_constant (&e))
abort ();
switch (extract_type (&e)) {
case ev_entity: case ev_entity:
tab = entity_imm_defs; tab = entity_imm_defs;
type = &type_entity; type = &type_entity;
@ -195,15 +191,14 @@ ReuseConstant (expr_t *expr, def_t *def)
type = &type_integer; type = &type_integer;
break; break;
} }
e.e.value.v.float_val = expr_integer (&e); val.v.float_val = val.v.integer_val;
e.e.value.type = ev_float; val.type = ev_float;
e.type = ex_value;
case ev_float: case ev_float:
tab = float_imm_defs; tab = float_imm_defs;
type = &type_float; type = &type_float;
break; break;
case ev_string: case ev_string:
e.e.value.v.integer_val = ReuseString (expr_string (&e)); val.v.integer_val = ReuseString (val.v.string_val);
tab = string_imm_defs; tab = string_imm_defs;
type = &type_string; type = &type_string;
break; break;
@ -218,7 +213,7 @@ ReuseConstant (expr_t *expr, def_t *def)
default: default:
abort (); abort ();
} }
memcpy (&search.i, &e.e, sizeof (search.i)); memcpy (&search.i, &val.v, sizeof (search.i));
imm = (immediate_t *) Hash_FindElement (tab, &search); imm = (immediate_t *) Hash_FindElement (tab, &search);
if (imm && strcmp (imm->def->name, ".zero") == 0) { if (imm && strcmp (imm->def->name, ".zero") == 0) {
if (def) { if (def) {
@ -263,12 +258,12 @@ ReuseConstant (expr_t *expr, def_t *def)
cn->initialized = cn->constant = 1; cn->initialized = cn->constant = 1;
cn->nosave = 1; cn->nosave = 1;
// copy the immediate to the global area // copy the immediate to the global area
switch (e.e.value.type) { switch (val.type) {
case ev_string: case ev_string:
reloc_def_string (cn); reloc_def_string (cn);
break; break;
case ev_func: case ev_func:
if (e.e.value.v.func_val) { if (val.v.func_val) {
reloc_t *reloc; reloc_t *reloc;
reloc = new_reloc (cn->space, cn->offset, rel_def_func); reloc = new_reloc (cn->space, cn->offset, rel_def_func);
reloc->next = pr.relocs; reloc->next = pr.relocs;
@ -276,24 +271,24 @@ ReuseConstant (expr_t *expr, def_t *def)
} }
break; break;
case ev_field: case ev_field:
if (e.e.value.v.pointer.def) if (val.v.pointer.def)
reloc_def_field_ofs (e.e.value.v.pointer.def, cn); reloc_def_field_ofs (val.v.pointer.def, cn);
break; break;
case ev_pointer: case ev_pointer:
if (e.e.value.v.pointer.def) { if (val.v.pointer.def) {
EMIT_DEF_OFS (pr.near_data, D_INT (cn), EMIT_DEF_OFS (pr.near_data, D_INT (cn),
e.e.value.v.pointer.def); val.v.pointer.def);
} }
break; break;
default: default:
break; break;
} }
memcpy (D_POINTER (void, cn), &e.e, 4 * type_size (type)); memcpy (D_POINTER (void, cn), &val.v, 4 * type_size (type));
imm = malloc (sizeof (immediate_t)); imm = malloc (sizeof (immediate_t));
imm->def = cn; imm->def = cn;
memcpy (&imm->i, &e.e, sizeof (imm->i)); memcpy (&imm->i, &val.v, sizeof (imm->i));
Hash_AddElement (tab, imm); Hash_AddElement (tab, imm);