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
#define __immediate_h
struct expr_s;
struct def_s *ReuseConstant (struct expr_s *expr, struct def_s *def);
struct ex_value_s;
struct def_s *emit_value (struct ex_value_s *value, struct def_s *def);
int ReuseString (const char *str);

View file

@ -65,7 +65,6 @@ static def_t zero_def;
static def_t *
get_value_def (ex_value_t *value, etype_t type)
{
//FIXME share immediates
def_t *def;
if (type == ev_short) {
@ -73,14 +72,7 @@ get_value_def (ex_value_t *value, etype_t type)
def->offset = value->v.short_val;
return def;
}
def = new_def (".imm", ev_types[type], pr.near_data, st_static);
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;
return emit_value (value, 0);
}
static def_t *

View file

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