Commit 438736a1 438736a1f29822b69387e616ed93f2aba1e70f62 by Sergey Poznyakoff

Changed type of `prog' to mh_instr_t, which is

a union of all objects that can be held in a program text
cell. This fixes potential problems due to sizeof(int)!=
sizeof(void*).
1 parent 448ea96c
......@@ -116,14 +116,31 @@ enum mh_type
};
typedef int mh_opcode_t;
struct mh_machine;
typedef void (*mh_builtin_fp)(struct mh_machine *);
typedef union {
mh_opcode_t opcode;
mh_builtin_fp builtin;
int num;
void *ptr;
char str[1]; /* Any number of characters follows */
} mh_instr_t;
#define MHI_OPCODE(m) (m).opcode
#define MHI_BUILTIN(m) (m).builtin
#define MHI_NUM(m) (m).num
#define MHI_PTR(m) (m).ptr
#define MHI_STR(m) (m).str
typedef struct mh_format mh_format_t;
struct mh_format
{
size_t progsize; /* Size of allocated program*/
mh_opcode_t *prog; /* Program itself */
mh_instr_t *prog; /* Program itself */
};
struct mh_machine;
typedef void (*mh_builtin_fp)(struct mh_machine *);
typedef struct mh_builtin mh_builtin_t;
......@@ -165,6 +182,8 @@ void mh_error(const char *fmt, ...);
FILE *mh_audit_open (char *name, mailbox_t mbox);
void mh_audit_close (FILE *fp);
int mh_message_number (message_t msg, size_t *pnum);
void *xmalloc (size_t);
void *xrealloc (void *, size_t);
......
......@@ -218,29 +218,29 @@ cntl : if cond list end elif_part else_part fi
/* Fixup first condition */
if ($5.cond)
format.prog[$2] = $5.cond - $2;
MHI_NUM(format.prog[$2]) = $5.cond - $2;
else if ($6)
format.prog[$2] = $6 - $2;
MHI_NUM(format.prog[$2]) = $6 - $2;
else
format.prog[$2] = $7.cond - $2;
MHI_NUM(format.prog[$2]) = $7.cond - $2;
/* Link all "false" lists */
if ($5.cond)
{
start_pc = $5.end;
end_pc = $5.end;
for (; format.prog[end_pc]; end_pc = format.prog[end_pc])
;
while (MHI_NUM(format.prog[end_pc]))
end_pc = MHI_NUM(format.prog[end_pc]);
}
if (start_pc)
format.prog[end_pc] = $4;
MHI_NUM(format.prog[end_pc]) = $4;
else
start_pc = $4;
/* Now, fixup the end branches */
branch_fixup (start_pc, $7.end);
format.prog[start_pc] = $7.end - start_pc;
MHI_NUM(format.prog[start_pc]) = $7.end - start_pc;
}
;
......@@ -300,7 +300,7 @@ elif_part : /* empty */
| elif_list end
{
$$.cond = $1.cond;
format.prog[$2] = $1.end;
MHI_NUM(format.prog[$2]) = $1.end;
$$.end = $2;
}
;
......@@ -308,14 +308,14 @@ elif_part : /* empty */
elif_list : elif cond list
{
$$.cond = $1;
format.prog[$2] = pc - $2 + 2;
MHI_NUM(format.prog[$2]) = pc - $2 + 2;
$$.end = 0;
}
| elif_list end elif cond list
{
format.prog[$4] = pc - $4 + 2;
MHI_NUM(format.prog[$4]) = pc - $4 + 2;
$$.cond = $1.cond;
format.prog[$2] = $1.end;
MHI_NUM(format.prog[$2]) = $1.end;
$$.end = $2;
}
;
......@@ -508,11 +508,11 @@ backslash(int c)
void
branch_fixup (size_t epc, size_t tgt)
{
size_t prev = format.prog[epc];
size_t prev = MHI_NUM(format.prog[epc]);
if (!prev)
return;
branch_fixup (prev, tgt);
format.prog[prev] = tgt - prev - 1;
MHI_NUM(format.prog[prev]) = tgt - prev - 1;
}
......@@ -534,36 +534,47 @@ size_t
mh_code_string (char *string)
{
int length = strlen (string) + 1;
size_t count = (length + sizeof (mh_opcode_t)) / sizeof (mh_opcode_t);
size_t count = (length + sizeof (mh_instr_t)) / sizeof (mh_instr_t);
size_t start_pc = pc;
mh_code_op (mhop_str_arg);
prog_reserve (count);
format.prog[pc++] = (mh_opcode_t) count;
memcpy (&format.prog[pc], string, length);
MHI_NUM(format.prog[pc++]) = count;
memcpy (MHI_STR(format.prog[pc]), string, length);
pc += count;
return start_pc;
}
size_t
mh_code_op (mh_opcode_t op)
mh_code (mh_instr_t *instr)
{
prog_reserve (1);
format.prog[pc] = op;
format.prog[pc] = *instr;
return pc++;
}
size_t
mh_code_op (mh_opcode_t op)
{
mh_instr_t instr;
MHI_OPCODE(instr) = op;
return mh_code(&instr);
}
size_t
mh_code_number (int num)
{
mh_instr_t instr;
size_t ret = mh_code_op (mhop_num_arg);
mh_code_op ((mh_opcode_t) num);
MHI_NUM(instr) = num;
mh_code (&instr);
return ret;
}
size_t
mh_code_builtin (mh_builtin_t *bp, int argtype)
{
mh_instr_t instr;
size_t start_pc = pc;
if (bp->argtype != argtype)
{
......@@ -607,7 +618,8 @@ mh_code_builtin (mh_builtin_t *bp, int argtype)
}
}
mh_code_op (mhop_call);
mh_code_op ((mh_opcode_t)bp->fun);
MHI_BUILTIN(instr) = bp->fun;
mh_code (&instr);
return start_pc;
}
......
......@@ -39,7 +39,7 @@ struct mh_machine
size_t pc; /* Program counter */
size_t progsize; /* Size of allocated program*/
mh_opcode_t *prog; /* Program itself */
mh_instr_t *prog; /* Program itself */
int stop; /* Stop execution immediately */
char *outbuf; /* Output buffer */
......@@ -184,14 +184,14 @@ mh_format (mh_format_t *fmt, message_t msg, size_t msgno,
while (!mach.stop)
{
mh_opcode_t opcode;
switch (opcode = mach.prog[mach.pc++])
switch (opcode = MHI_OPCODE(mach.prog[mach.pc++]))
{
case mhop_stop:
mach.stop = 1;
break;
case mhop_branch:
mach.pc += mach.prog[mach.pc];
mach.pc += MHI_NUM(mach.prog[mach.pc]);
break;
case mhop_num_asgn:
......@@ -203,33 +203,33 @@ mh_format (mh_format_t *fmt, message_t msg, size_t msgno,
break;
case mhop_num_arg:
mach.arg_num = mach.prog[mach.pc++];
mach.arg_num = MHI_NUM(mach.prog[mach.pc++]);
break;
case mhop_str_arg:
{
size_t skip = mach.prog[mach.pc++];
strobj_set (&mach.arg_str, (char*)&mach.prog[mach.pc]);
size_t skip = MHI_NUM(mach.prog[mach.pc++]);
strobj_set (&mach.arg_str, MHI_STR(mach.prog[mach.pc]));
mach.pc += skip;
}
break;
case mhop_num_branch:
if (!mach.arg_num)
mach.pc += mach.prog[mach.pc];
mach.pc += MHI_NUM(mach.prog[mach.pc]);
else
mach.pc++;
break;
case mhop_str_branch:
if (!*strobj_ptr (&mach.arg_str))
mach.pc += mach.prog[mach.pc];
mach.pc += MHI_NUM(mach.prog[mach.pc]);
else
mach.pc++;
break;
case mhop_call:
(*(mh_builtin_fp) mach.prog[mach.pc++]) (&mach);
MHI_BUILTIN (mach.prog[mach.pc++]) (&mach);
break;
case mhop_header:
......@@ -369,7 +369,7 @@ mh_format (mh_format_t *fmt, message_t msg, size_t msgno,
break;
case mhop_fmtspec:
mach.fmtflags = mach.prog[mach.pc++];
mach.fmtflags = MHI_NUM(mach.prog[mach.pc++]);
break;
default:
......