aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2007-03-31 20:31:40 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2007-03-31 20:31:40 +0000
commit86be9fa5494be9417f90f16f87eca6ab2a28631d (patch)
treea3bd15dc99defd2413d1a0af10e946c6b6d0c01b
parent5633a8204a428a28582225810f215b23445037d5 (diff)
downloadmailfromd-86be9fa5494be9417f90f16f87eca6ab2a28631d.tar.gz
mailfromd-86be9fa5494be9417f90f16f87eca6ab2a28631d.tar.bz2
Switch to flat address space model. Data space (and stack) contain
only references to objects within the data space (virtual addresses), no actual pointers are passed. * src/snarf.m4 (MF_ALLOC_HEAP, MF_COPY_STRING): Take two arguments (MF_BEGIN_TEMP_SPACE): Use env_data_ref (MF_VAR_SET_STRING): New macro * src/bi_poll.m4, src/bi_string.m4, src/bi_dns.m4, src/bi_spf.m4, src/bi_sa.m4, src/bi_vars.m4, src/bi_db.m4: Use new heap allocation macros. * src/drivers.c (code_memref, code_type_string): Use opcode_push (code_type_variable): Remove opcode_svalidate. This time for good * src/mailfromd.h (env_throw_0): Change signature * src/prog.c (struct eval_environ.stack): Remove. Use plain addressing model. All references updated. (env_reference,env_var_ref): Remove (heap_reserve_words, heap_reserve): Return offset into the data space instead of the pointer. All uses updated. (env_data_ref): New function * src/opcodes (MEMEXT,MEM,SVALIDATE): Remove * src/prog.h (env_data_ref): New function (heap_reserve_words): New function (heap_reserve): Return size_t * TODO: Update git-svn-id: file:///svnroot/mailfromd/trunk@1331 7a8a7f39-df28-0410-adc6-e0d955640f24
-rw-r--r--TODO2
-rw-r--r--src/bi_db.m45
-rw-r--r--src/bi_dns.m47
-rw-r--r--src/bi_poll.m413
-rw-r--r--src/bi_sa.m44
-rw-r--r--src/bi_spf.m46
-rw-r--r--src/bi_string.m430
-rw-r--r--src/bi_vars.m42
-rw-r--r--src/drivers.c6
-rw-r--r--src/mailfromd.h2
-rw-r--r--src/opcodes3
-rw-r--r--src/prog.c256
-rw-r--r--src/prog.h5
-rw-r--r--src/snarf.m423
14 files changed, 155 insertions, 209 deletions
diff --git a/TODO b/TODO
index 2bbf3b45..0becaa5b 100644
--- a/TODO
+++ b/TODO
@@ -8,6 +8,8 @@ Mailfromd TODO list.
* Various items by Jan (ref <Pine.LNX.4.58.0610112345080.2162@cedric.unob.cz>)
+* gsub(regex, repl, string)
+
** Implement still more string functions
* If an optional numeric argument to a built-in function has value 0 it is
diff --git a/src/bi_db.m4 b/src/bi_db.m4
index 816ecc58..fecc0eb8 100644
--- a/src/bi_db.m4
+++ b/src/bi_db.m4
@@ -53,11 +53,12 @@ dbmap_lookup(eval_environ_t env, char *dbname, const char *keystr,
else
push(env, 0);
} else if (((char*)MU_DATUM_PTR(contents))[MU_DATUM_SIZE(contents)-1]) {
+ size_t off;
size_t len = MU_DATUM_SIZE(contents);
- char *s = MF_ALLOC_HEAP(len + 1);
+ char *s = MF_ALLOC_HEAP(off, len + 1);
memcpy(s, MU_DATUM_PTR(contents), len);
s[len] = 0;
- push(env, (STKVAL) s);
+ push(env, (STKVAL) off);
} else
pushs(env, MU_DATUM_PTR(contents));
}
diff --git a/src/bi_dns.m4 b/src/bi_dns.m4
index 021f2d08..a7d8b214 100644
--- a/src/bi_dns.m4
+++ b/src/bi_dns.m4
@@ -189,7 +189,7 @@ END
MF_DEFUN(domainpart, STRING, STRING str)
{
char *p = strchr(str, '@');
- MF_RETURN(p ? p+1 : str);
+ MF_RETURN_STRING(p ? p+1 : str);
}
END
@@ -198,11 +198,12 @@ MF_DEFUN(localpart, STRING, STRING str)
char *p = strchr(str, '@');
if (p) {
+ size_t off;
size_t size = p - str;
- char *string_space = MF_ALLOC_HEAP(size + 1);
+ char *string_space = MF_ALLOC_HEAP(off, size + 1);
memcpy(string_space, str, size);
string_space[size] = 0;
- MF_RETURN(string_space);
+ MF_RETURN(off);
} else
MF_RETURN_STRING(str);
}
diff --git a/src/bi_poll.m4 b/src/bi_poll.m4
index c61605ab..d9f1eeeb 100644
--- a/src/bi_poll.m4
+++ b/src/bi_poll.m4
@@ -26,14 +26,11 @@ set_last_poll_result(eval_environ_t env,
const char *host_addr,
const char *send, const char *recv)
{
- char *s;
-
- s = host_addr ? MF_COPY_STRING(host_addr) : NULL;
- MF_VAR_REF(last_poll_host, s);
- s = send ? MF_COPY_STRING(send) : NULL;
- MF_VAR_REF(last_poll_send, s);
- s = recv ? MF_COPY_STRING(recv) : NULL;
- MF_VAR_REF(last_poll_recv, s);
+ size_t s;
+
+ MF_VAR_SET_STRING(last_poll_host, host_addr);
+ MF_VAR_SET_STRING(last_poll_send, send);
+ MF_VAR_SET_STRING(last_poll_recv, recv);
}
void
diff --git a/src/bi_sa.m4 b/src/bi_sa.m4
index bd66b79d..c3734fe4 100644
--- a/src/bi_sa.m4
+++ b/src/bi_sa.m4
@@ -403,7 +403,7 @@ MF_DEFUN(sa, NUMBER, STRING urlstr, NUMBER prec)
MF_VAR_REF(sa_score, score);
MF_VAR_REF(sa_threshold, threshold);
- MF_VAR_REF(sa_keywords, MF_COPY_STRING(buffer));
+ MF_VAR_SET_STRING(sa_keywords, buffer);
while (spamd_read_line(ostr, buffer, sizeof buffer, &size) == 0
&& size > 0)
@@ -485,7 +485,7 @@ MF_DEFUN(clamav, NUMBER, STRING urlstr)
s = buffer;
else
s++;
- MF_VAR_REF(clamav_virus_name, MF_COPY_STRING(s));
+ MF_VAR_SET_STRING(clamav_virus_name, s);
debug2(2,
"%sclamav found %s",
diff --git a/src/bi_spf.m4 b/src/bi_spf.m4
index ad4b7407..a09a7bce 100644
--- a/src/bi_spf.m4
+++ b/src/bi_spf.m4
@@ -26,10 +26,8 @@ MF_VAR(spf_explanation_prefix, STRING);
static void
update_spf_vars(eval_environ_t env, spf_answer_t *ans)
{
- char *s = ans->exp_text ? MF_COPY_STRING(ans->exp_text) : NULL;
- MF_VAR_REF(spf_explanation, s);
- s = ans->mech ? MF_COPY_STRING(ans->mech) : NULL;
- MF_VAR_REF(spf_mechanism, s);
+ MF_VAR_SET_STRING(spf_explanation, ans->exp_text);
+ MF_VAR_SET_STRING(spf_mechanism, ans->mech);
MF_VAR_REF(spf_ttl, ans->ttl);
}
diff --git a/src/bi_string.m4 b/src/bi_string.m4
index 874b783f..2326aead 100644
--- a/src/bi_string.m4
+++ b/src/bi_string.m4
@@ -18,21 +18,23 @@
MF_DEFUN(toupper, STRING, STRING string)
{
- char *s = MF_COPY_STRING(string);
+ size_t off;
+ char *s = MF_COPY_STRING(off, string);
char *p;
for (p = s; *p; p++)
*p = toupper(*p);
- MF_RETURN(s);
+ MF_RETURN(off);
}
END
MF_DEFUN(tolower, STRING, STRING string)
{
- char *s = MF_COPY_STRING(string);
+ size_t off;
+ char *s = MF_COPY_STRING(off, string);
char *p;
for (p = s; *p; p++)
*p = tolower(*p);
- MF_RETURN(s);
+ MF_RETURN(off);
}
END
@@ -44,6 +46,7 @@ END
MF_DEFUN(substring, STRING, STRING string, NUMBER start, NUMBER end)
{
+ size_t off;
long len = strlen(string);
char *s;
@@ -59,16 +62,17 @@ MF_DEFUN(substring, STRING, STRING string, NUMBER start, NUMBER end)
"argument out of range");
len = end - start + 1;
- s = MF_ALLOC_HEAP(len + 1);
+ s = MF_ALLOC_HEAP(off, len + 1);
memcpy(s, string + start, len);
s[len] = 0;
- MF_RETURN(s);
+ MF_RETURN(off);
}
END
MF_DEFUN(substr, STRING, STRING string, NUMBER start, OPTIONAL, NUMBER nbytes)
{
+ size_t off;
long len = strlen(string);
char *s;
@@ -76,11 +80,11 @@ MF_DEFUN(substr, STRING, STRING string, NUMBER start, OPTIONAL, NUMBER nbytes)
if (nbytes == 0)
nbytes = len - start;
- s = MF_ALLOC_HEAP(nbytes + 1);
+ s = MF_ALLOC_HEAP(off, nbytes + 1);
memcpy(s, string + start, nbytes);
s[nbytes] = 0;
- MF_RETURN(s);
+ MF_RETURN(off);
}
END
@@ -127,12 +131,13 @@ MF_DEFUN(revstr, STRING, STRING str)
{
int len = strlen(str);
char *p;
- char *s = MF_ALLOC_HEAP(len + 1);
+ size_t off;
+ char *s = MF_ALLOC_HEAP(off, len + 1);
s[len] = 0;
for (p = s + len - 1; p >= s; p--, str++)
*p = *str;
- MF_RETURN(s);
+ MF_RETURN(off);
}
END
@@ -167,9 +172,10 @@ END
MF_DEFUN(unfold, STRING, STRING text)
{
- char *s = MF_COPY_STRING(text);
+ size_t off;
+ char *s = MF_COPY_STRING(off, text);
mu_string_unfold(s, NULL);
- pushs(env, s);
+ MF_RETURN(off);
}
END
diff --git a/src/bi_vars.m4 b/src/bi_vars.m4
index 156daf91..aca795b4 100644
--- a/src/bi_vars.m4
+++ b/src/bi_vars.m4
@@ -24,7 +24,7 @@ MF_VAR(mailfrom_address, STRING);
unsigned long
get_rcpt_count(eval_environ_t env)
{
- return (long) MF_VAR_REF(rcpt_count);
+ return (long) MF_VAR_REF(rcpt_count);
}
void
diff --git a/src/drivers.c b/src/drivers.c
index e66cf5b8..2e9c7c01 100644
--- a/src/drivers.c
+++ b/src/drivers.c
@@ -32,7 +32,7 @@ code_memref(NODE *node)
{
switch (node->v.var_ref.variable->storage_class) {
case storage_extern:
- code_op(opcode_memext);
+ code_op(opcode_push);
code_immediate((void*)node->v.var_ref.variable->off);
break;
@@ -76,7 +76,7 @@ void
code_type_string(NODE *node, struct locus **old_locus)
{
MARK_LOCUS();
- code_op(opcode_memext);
+ code_op(opcode_push);
code_immediate((const void*)node->v.literal->off);
}
@@ -1148,8 +1148,6 @@ code_type_variable(NODE *node, struct locus **old_locus)
MARK_LOCUS();
code_memref(node);
code_op(opcode_deref);
- if (node->v.var_ref.variable->type == dtype_string)
- code_op(opcode_svalidate);
}
diff --git a/src/mailfromd.h b/src/mailfromd.h
index 390c9f37..a292a743 100644
--- a/src/mailfromd.h
+++ b/src/mailfromd.h
@@ -759,7 +759,7 @@ void env_init(eval_environ_t env);
void env_throw(eval_environ_t env, mf_status status,
const char *fmt, ...) ATTRIBUTE_NORETURN;
void env_throw_0(eval_environ_t env, mf_status status,
- const char *text) ATTRIBUTE_NORETURN;
+ size_t text_off) ATTRIBUTE_NORETURN;
void env_push_string(eval_environ_t env, char *arg);
void env_push_number(eval_environ_t env, long arg);
diff --git a/src/opcodes b/src/opcodes
index cd0aaf2a..69637006 100644
--- a/src/opcodes
+++ b/src/opcodes
@@ -76,12 +76,9 @@ LOGNOT NULL 0
CONCAT NULL 0
MEMSTK dump_memstk 2
-MEMEXT dump_memext 1
-MEM NULL 0
DEREF NULL 0
ASGN NULL 0
BUILTIN dump_builtin 2
-SVALIDATE NULL 0
CATCH dump_catch 3
THROW dump_throw 1
diff --git a/src/prog.c b/src/prog.c
index 780e3bf6..7cc0a307 100644
--- a/src/prog.c
+++ b/src/prog.c
@@ -230,9 +230,9 @@ disable_prog_trace(const char *modlist)
struct eval_environ {
prog_counter_t pc; /* Program counter */
- STKVAL *stack; /* Stack space */
- prog_counter_t tos; /* Top of stack: 0 <= tos <= toh */
- prog_counter_t toh; /* Top of heap: tos <= toh <= stack_size */
+ prog_counter_t tos; /* Top of stack: datasize <= tos <= toh */
+ prog_counter_t toh; /* Top of heap:
+ tos <= toh <= datasize + stack_size */
prog_counter_t base; /* Base pointer */
STKVAL reg; /* General purpose register */
STKVAL *dataseg; /* Data space */
@@ -285,34 +285,14 @@ env_base(eval_environ_t env, size_t frame)
{
size_t base = env->base;
for (; frame; frame--)
- base = (size_t) env->stack[base-1];
+ base = (size_t) env->dataseg[base-1];
return base;
}
-STKVAL *
-env_reference(eval_environ_t env, storage_class_t sc, size_t n, size_t frame)
-{
- switch (sc) {
- case storage_extern:
- return &env->dataseg[n];
- case storage_auto:
- return &env->stack[env_base(env, frame) + n];
- case storage_param:
- return &env->stack[env_base(env, frame) - 2 - n];
- }
- abort();
-}
-
-STKVAL *
-env_var_ref(eval_environ_t env, size_t off)
-{
- return env_reference(env, storage_extern, off, 0);
-}
-
void
env_var_inc(eval_environ_t env, size_t off)
{
- ++*env_var_ref(env, off);
+ ++*env_data_ref(env, off);
}
const struct locus *
@@ -390,19 +370,19 @@ get_literal(eval_environ_t env, unsigned n)
STKVAL
get_arg(eval_environ_t env, unsigned n)
{
- return env->stack[env->tos - n - 1];
+ return env->dataseg[env->tos - n - 1];
}
char *
get_string_arg(eval_environ_t env, unsigned n)
{
- return (char*) get_arg(env, n);
+ return (char*) (env->dataseg + (size_t) get_arg(env, n));
}
size_t
get_numeric_arg(eval_environ_t env, unsigned n)
{
- return get_arg(env, n);
+ return (size_t) get_arg(env, n);
}
void
@@ -415,7 +395,7 @@ push(eval_environ_t env, STKVAL val)
runtime_error(env,
"Out of stack space; increase #pragma stacksize");
}
- env->stack[env->tos++] = val;
+ env->dataseg[env->tos++] = val;
}
STKVAL
@@ -423,14 +403,12 @@ pop(eval_environ_t env)
{
if (env->tos == 0)
runtime_error(env, "Stack underflow");
- return env->stack[--env->tos];
+ return env->dataseg[--env->tos];
}
-STKVAL
-heap_reserve(eval_environ_t env, size_t size)
+size_t
+heap_reserve_words(eval_environ_t env, size_t words)
{
- size_t words = B2STACK(size);
-
if (env->toh - words <= env->tos) {
/* Heap overrun: */
/* gc(); */
@@ -439,7 +417,13 @@ heap_reserve(eval_environ_t env, size_t size)
"Heap overrun; increase #pragma stacksize");
}
env->toh -= words;
- return env->stack + env->toh--;
+ return env->toh--;
+}
+
+size_t
+heap_reserve(eval_environ_t env, size_t size)
+{
+ return heap_reserve_words(env, B2STACK(size));
}
STKVAL
@@ -454,15 +438,15 @@ heap_tempspace(eval_environ_t env, size_t size)
runtime_error(env,
"Heap overrun; increase #pragma stacksize");
}
- return env->stack + env->toh - words;
+ return env->dataseg + env->toh - words;
}
STKVAL
heap_max_tempspace(eval_environ_t env, size_t *size)
{
- *size = (env->toh - env->tos - 1) * sizeof env->stack[0];
- return env->stack + env->tos + 1;
+ *size = (env->toh - env->tos - 1) * sizeof env->dataseg[0];
+ return env->dataseg + env->tos + 1;
}
STKVAL
@@ -475,14 +459,22 @@ heap_fix_tempspace(eval_environ_t env, size_t size)
"INTERNAL ERROR: memory chunk too big "
"to fit into heap");
env->toh -= words;
- memmove(env->stack + env->toh, env->stack + env->tos + 1, size);
- return env->stack + env->toh--;
+ memmove(env->dataseg + env->toh, env->dataseg + env->tos + 1, size);
+ return env->dataseg + env->toh--;
+}
+
+STKVAL *
+env_data_ref(eval_environ_t env, size_t off)
+{
+ return env->dataseg + off;
}
void
pushs(eval_environ_t env, char *s)
{
- push(env, (STKVAL) strcpy(heap_reserve(env, strlen(s) + 1), s));
+ size_t off = heap_reserve(env, strlen(s) + 1);
+ strcpy((char*) env_data_ref(env, off), s);
+ push(env, (STKVAL) off);
}
/* Auxiliary instructions */
@@ -509,9 +501,9 @@ void
instr_xchg(eval_environ_t env)
{
prog_counter_t p = env->tos - 1;
- STKVAL tmp = env->stack[p];
- env->stack[p] = env->stack[p - 1];
- env->stack[p - 1] = tmp;
+ STKVAL tmp = env->dataseg[p];
+ env->dataseg[p] = env->dataseg[p - 1];
+ env->dataseg[p - 1] = tmp;
if (PROG_TRACE_ENGINE)
prog_trace(env, "XCHG");
}
@@ -552,13 +544,13 @@ instr_memstk(eval_environ_t env)
{
size_t frame = (size_t) get_immediate(env, 0);
long off = (long) get_immediate(env, 1);
- STKVAL val = (STKVAL) &env->stack[env_base(env, frame) + off];
+ size_t val = env_base(env, frame) + off;
advance_pc(env, 2);
if (PROG_TRACE_ENGINE)
- prog_trace(env, "MEMSTK %lu(%ld)=%08x",
+ prog_trace(env, "MEMSTK %lu(%ld)=%lu",
(unsigned long) frame, off,
- val);
- push(env, val);
+ (unsigned long) val);
+ push(env, (STKVAL) val);
}
void
@@ -568,70 +560,16 @@ dump_memstk(prog_counter_t i)
}
void
-instr_memext(eval_environ_t env)
-{
- size_t off = (size_t) get_immediate(env, 0);
- STKVAL val = (STKVAL) &env->dataseg[off];
- advance_pc(env, 1);
- if (PROG_TRACE_ENGINE)
- prog_trace(env, "MEMEXT %08x=%08x",
- (unsigned long) off,
- val);
- push(env, val);
-}
-
-void
-dump_memext(prog_counter_t i)
-{
- printf("%08x", (unsigned long) prog[i]);
-}
-
-void
-instr_mem(eval_environ_t env)
-{
- size_t frame = (size_t) get_numeric_arg(env, 2);
- size_t off = (size_t) get_numeric_arg(env, 1);
- storage_class_t class = (storage_class_t) get_numeric_arg(env, 0);
- adjust_stack(env, 3);
-
- if (PROG_TRACE_ENGINE)
- prog_trace(env, "LOC %s %lu(%lu)",
- storage_class_str(class),
- (unsigned long) frame,
- (unsigned long) off);
- push(env, (STKVAL) env_reference(env, class, off, frame));
-}
-
-void
instr_deref(eval_environ_t env)
{
- STKVAL *p = (STKVAL*) get_arg(env, 0);
+ size_t off = (size_t) get_arg(env, 0);
+ STKVAL val = env->dataseg[off];
adjust_stack(env, 1);
if (PROG_TRACE_ENGINE)
- prog_trace(env, "DEREF %p=%p", p, *p);
- push(env, *p);
-}
-
-
-void
-instr_push_literal(eval_environ_t env)
-{
- size_t s = (size_t) get_immediate(env, 0);
- char *p = (char*) (env->dataseg + s);
- if (PROG_TRACE_ENGINE)
- prog_trace(env, "PUSH_LITERAL %08lx %s",
- (unsigned long) s, p);
- push(env, p);
- advance_pc(env, 1);
-}
-
-void
-dump_push_literal(prog_counter_t i)
-{
- size_t s = (size_t) prog[i];
- char *p = (char*) (dataseg + s);
-
- printf("%08lx %s", (unsigned long) s, p);
+ prog_trace(env, "DEREF %lu=%lu (%p)",
+ (unsigned long) off,
+ (unsigned long) val, val);
+ push(env, val);
}
void
@@ -654,7 +592,6 @@ void
instr_backref(eval_environ_t env)
{
unsigned n = (unsigned) get_immediate(env, 0);
- char *s;
size_t matchlen;
if (PROG_TRACE_ENGINE)
@@ -673,13 +610,17 @@ instr_backref(eval_environ_t env)
}
if (env->matches[n].rm_so == -1) {
- push(env, env->dataseg);
+ push(env, 0);
} else {
+ char *s;
+ size_t off;
+
matchlen = env->matches[n].rm_eo - env->matches[n].rm_so;
- s = heap_reserve(env, matchlen + 1);
+ off = heap_reserve(env, matchlen + 1);
+ s = (char*) env_data_ref(env, off);
memcpy(s, env->string + env->matches[n].rm_so, matchlen);
s[matchlen] = 0;
- push(env, (STKVAL) s);
+ push(env, (STKVAL) off);
}
}
@@ -693,10 +634,11 @@ dump_backref(prog_counter_t i)
void
instr_ston(eval_environ_t env)
{
- char *s = pop(env);
+ char *s = get_string_arg(env, 0);
char *p;
long v = strtol(s, &p, 0);
+ adjust_stack(env, 1);
if (PROG_TRACE_ENGINE)
prog_trace(env, "STON %s", s);
if (*p)
@@ -713,9 +655,9 @@ instr_ntos(eval_environ_t env)
long v = (long) get_numeric_arg(env, 0);
char buf[NUMERIC_BUFSIZE_BOUND];
+ adjust_stack(env, 1);
if (PROG_TRACE_ENGINE)
prog_trace(env, "NTOS %ld", v);
- adjust_stack(env, 1);
snprintf(buf, sizeof buf, "%ld", v);
pushs(env, buf);
@@ -738,6 +680,7 @@ instr_symbol(eval_environ_t env)
{
char *symbol = (char *) get_literal(env, 0);
char *s = env->getsym(env->data, symbol);
+
if (PROG_TRACE_ENGINE)
prog_trace(env, "SYMBOL %s", symbol);
if (!s) {
@@ -751,8 +694,9 @@ instr_symbol(eval_environ_t env)
if (PROG_TRACE_ENGINE)
prog_trace(env, "%s dereferenced to %s", symbol, s);
- pushs(env, (STKVAL) s);
advance_pc(env, 1);
+
+ pushs(env, s);
}
void
@@ -1067,8 +1011,7 @@ instr_regex(eval_environ_t env)
regex_flags_to_string(regtab[index].regflags,
buffer,
sizeof buffer),
- env_reference(env, storage_extern,
- regtab[index].expr, 0));
+ (char*) env_data_ref(env, regtab[index].expr));
push(env, (STKVAL) index);
}
@@ -1350,13 +1293,14 @@ instr_concat(eval_environ_t env)
{
char *left = get_string_arg(env, 1);
char *right = get_string_arg(env, 0);
- char *res = heap_reserve(env, strlen(left) + strlen(right) + 1);
+ size_t off = heap_reserve(env, strlen(left) + strlen(right) + 1);
+ char *res = (char*) env_data_ref(env, off);
strcat(strcpy(res, left), right);
adjust_stack(env, 2);
if (PROG_TRACE_ENGINE)
prog_trace(env, "CONCAT ('%s','%s')='%s'", left, right, res);
- push(env, (STKVAL) res);
+ push(env, (STKVAL) off);
}
void
@@ -1369,26 +1313,16 @@ void
instr_asgn(eval_environ_t env)
{
STKVAL val = get_arg(env, 1);
- STKVAL *dest = (STKVAL*)get_arg(env, 0);
+ size_t dest = get_numeric_arg(env, 0);
adjust_stack(env, 2);
if (PROG_TRACE_ENGINE)
- prog_trace(env, "ASGN %p=%p",
- dest,
- val);
- *dest = val;
+ prog_trace(env, "ASGN %lu=%lu",
+ (unsigned long) dest,
+ (unsigned long) val);
+ env->dataseg[dest] = val;
}
void
-instr_svalidate(eval_environ_t env)
-{
- STKVAL val = get_arg(env, 0);
- if (PROG_TRACE_ENGINE)
- prog_trace(env, "SVALIDATE %p", val);
- if (val == 0)
- env->stack[env->tos - 1] = env->dataseg;
-}
-
-void
instr_catch(eval_environ_t env)
{
long off = (long) get_immediate(env, 0);
@@ -1427,12 +1361,12 @@ void
instr_throw(eval_environ_t env)
{
unsigned long n = (unsigned long) get_immediate(env, 0);
- char *str = get_string_arg(env, 0);
+ size_t off = (size_t) get_arg(env, 0);
advance_pc(env, 1);
adjust_stack(env, 1);
if (n > mf_status_count)
runtime_error(env, "Invalid exception number: %lu", n);
- env_throw_0(env, (mf_status) n, str);
+ env_throw_0(env, (mf_status) n, off);
}
void
@@ -1492,12 +1426,12 @@ dump_saveex(prog_counter_t i)
void
instr_restex(eval_environ_t env)
{
- unsigned exmask = (unsigned)env->stack[env->base];
+ unsigned exmask = (unsigned)env->dataseg[env->base];
int i;
for (i = 0; i < mf_status_count; i++) {
if (EXMASK(i) & exmask)
env->catch[i] = (prog_counter_t)
- env->stack[env->base+i+1];
+ env->dataseg[env->base+i+1];
}
}
@@ -1584,7 +1518,7 @@ instr_xlats(eval_environ_t env)
unsigned long count = (unsigned long) get_immediate(env, 0);
size_t off = (size_t) get_immediate(env, 1);
STKVAL *tab = (STKVAL *) (env->dataseg + off);
- char *str = (char*) env->reg;
+ char *str = (char*) env_data_ref(env, (size_t) env->reg);
if (PROG_TRACE_ENGINE)
prog_trace(env, "XLATS %lu %lu", count, (unsigned long) off);
@@ -1707,7 +1641,7 @@ env_init(eval_environ_t env)
/* Initialize status and registers */
env->status = SMFIS_CONTINUE;
- env->tos = 0;
+ env->tos = datasize;
env->base = 0;
env->reg = 0;
@@ -1798,20 +1732,21 @@ eval_environment(eval_environ_t env, prog_counter_t start)
return 0;
}
-char *
+size_t
env_vsprintf(eval_environ_t env, const char *fmt, va_list ap)
{
size_t size, n;
char *p;
char *s = heap_max_tempspace(env, &size);
+ size_t off;
n = vsnprintf(s, size, fmt, ap);
- p = heap_reserve(env, n+1);
+ p = (char*) env_data_ref(env, off = heap_reserve(env, n + 1));
memmove(p, s, n + 1);
- return p;
+ return off;
}
void
-env_throw_0(eval_environ_t env, mf_status status, const char *str)
+env_throw_0(eval_environ_t env, mf_status status, size_t off)
{
prog_counter_t pc = env->catch[status];
if (pc) {
@@ -1824,23 +1759,23 @@ env_throw_0(eval_environ_t env, mf_status status, const char *str)
/* Fixup the program counter */
env->pc = pc - 1;
/* Generate normal entry frame */
- push(env, (STKVAL) str); /* Pass the pointer */
+ push(env, (STKVAL) off);
env_push_number(env, status);
env_make_frame(env);
longjmp(env->catch_jmp, 1);
}
- runtime_error(env, "%s", str);
+ runtime_error(env, "%s", (char*) env_data_ref(env, off));
}
void
env_throw(eval_environ_t env, mf_status status, const char *fmt, ...)
{
va_list ap;
- char *str;
+ size_t off;
va_start(ap, fmt);
- str = env_vsprintf(env, fmt, ap);
+ off = env_vsprintf(env, fmt, ap);
va_end(ap);
- env_throw_0(env, status, str);
+ env_throw_0(env, status, off);
}
sfsistat
@@ -2083,8 +2018,6 @@ init_dataseg(STKVAL *dseg)
{
size_t i;
memcpy(dseg, dataseg, datasize * sizeof dataseg[0]);
- for (i = 0; i < dataseg_reloc_count; i++)
- dseg[dataseg_reloc[i]] = dseg + (size_t)dseg[dataseg_reloc[i]];
}
eval_environ_t
@@ -2102,13 +2035,12 @@ create_environment(SMFICTX *ctx,
exit(1);
}
- env->dataseg = calloc(stack_size + datasize, sizeof env->stack[0]);
+ env->dataseg = calloc(stack_size + datasize, sizeof env->dataseg[0]);
if (!env->dataseg) {
mu_error("Not enough memory");
exit(1);
}
- env->stack = env->dataseg + datasize;
init_dataseg(env->dataseg);
env->ctx = ctx;
@@ -2122,7 +2054,7 @@ create_environment(SMFICTX *ctx,
in env_init. The top of heap should be retained across calls to
handlers, since we store string variables there. This raises stack
size requirements. */
- env->toh = stack_size - 1;
+ env->toh = datasize + stack_size - 1;
env->bi_priv_array = NULL;
@@ -2290,28 +2222,30 @@ void
env_final_gc(eval_environ_t env)
{
size_t i;
- char *top = (char*)(env->stack + env->toh);
- char *bot = (char*)(env->stack + stack_size);
+ size_t top = env->toh;
+ size_t bot = datasize + stack_size;
genv = env;
/* Prepare s_off/s_count: remove any variables that are not
in heap */
s_off = xcalloc(dataseg_reloc_count, sizeof s_off[0]);
for (i = 0, s_cnt = 0; i < dataseg_reloc_count; i++) {
- char *p = (char*) env->dataseg[dataseg_reloc[i]];
+ size_t p = (size_t) env->dataseg[dataseg_reloc[i]];
if (top < p && p < bot)
s_off[s_cnt++] = dataseg_reloc[i];
}
qsort(s_off, s_cnt, sizeof s_off[0], s_off_cmp);
/* Compact the variables */
- env->toh = stack_size - 1;
+ env->toh = datasize + stack_size - 1;
for (i = 0; i < s_cnt; i++) {
size_t off = s_off[i];
- char *p = (char*) env->dataseg[off];
+ char *p = (char*) env_data_ref(env,
+ (size_t) env->dataseg[off]);
size_t len = strlen(p) + 1;
- char *q = (char*)(env->dataseg[off] = heap_reserve(env, len));
- memmove(q, p, len);
+ size_t q = heap_reserve(env, len);
+ memmove(env_data_ref(env, q), p, len);
+ env->dataseg[off] = (STKVAL) q;
}
free(s_off);
}
diff --git a/src/prog.h b/src/prog.h
index 19c969a1..f16ecce1 100644
--- a/src/prog.h
+++ b/src/prog.h
@@ -37,7 +37,9 @@ char *get_string_arg(eval_environ_t env, unsigned n);
size_t get_numeric_arg(eval_environ_t env, unsigned n);
void push(eval_environ_t env, STKVAL val);
STKVAL pop(eval_environ_t env);
-STKVAL heap_reserve(eval_environ_t env, size_t size);
+STKVAL *env_data_ref(eval_environ_t env, size_t off);
+size_t heap_reserve(eval_environ_t env, size_t size);
+size_t heap_reserve_words(eval_environ_t env, size_t size);
STKVAL heap_tempspace(eval_environ_t env, size_t size);
STKVAL heap_max_tempspace(eval_environ_t env, size_t *size);
STKVAL heap_fix_tempspace(eval_environ_t env, size_t size);
@@ -45,7 +47,6 @@ void pushs(eval_environ_t env, char *s);
void advance_pc(eval_environ_t env, unsigned cnt);
void adjust_stack(eval_environ_t env, unsigned cnt);
void prog_trace(eval_environ_t env, const char *fmt, ...);
-STKVAL *env_var_ref(eval_environ_t env, size_t off);
void env_var_inc(eval_environ_t env, size_t off);
char *env_dict_getsym(eval_environ_t env, char *string);
char *env_dict_install(eval_environ_t env, char *key, char *value);
diff --git a/src/snarf.m4 b/src/snarf.m4
index 7d58163c..064e4e7c 100644
--- a/src/snarf.m4
+++ b/src/snarf.m4
@@ -237,19 +237,20 @@ pushs(env, $1);
return;
} while (0)>])
-dnl MF_ALLOC_HEAP(len) - Allocate LEN bytes from the heap
+dnl MF_ALLOC_HEAP(off, len) - Allocate LEN bytes from the heap
dnl
-define([<MF_ALLOC_HEAP>],[<heap_reserve(env, $1)>])
+define([<MF_ALLOC_HEAP>],[<dnl
+(char*) env_data_ref(env, ([<$1>] = heap_reserve(env, $2)))>])
dnl MF_ALLOC_HEAP_TEMP(len) - Temporarly allocate LEN bytes from the heap.
dnl
define([<MF_ALLOC_HEAP_TEMP>],[<heap_tempspace(env, $1)>])
-dnl MF_COPY_STRING(string) - Copy STRING to the heap. Return the pointer to
-dnl the copy.
+dnl MF_COPY_STRING(off, string) - Copy STRING to the heap. Return the
+dnl pointer to the copy.
dnl
define([<MF_COPY_STRING>],[<dnl
-strcpy(heap_reserve(env, strlen($1) + 1), $1)>])
+strcpy((char*)env_data_ref(env, $1 = heap_reserve(env, strlen($2) + 1)), $2)>])
dnl MF_BEGIN_TEMP_SPACE(ptr,size) - Begin temporary space manipulations
dnl On return PTR will point to the temporary heap space capable of holding
@@ -288,7 +289,17 @@ dnl In one-argument form, return its value. In two-arguments form, assign
dnl the VALUE to it.
dnl
define([<MF_VAR_REF>],[<dnl
-*env_var_ref(env, $1_loc) ifelse($2,,,= (STKVAL) ($2))>])
+*env_data_ref(env, $1_loc) ifelse($2,,,= (STKVAL) ($2))>])
+
+dnl MF_VAR_SET_STRING(name, value) - Set variable NAME to the string VALUE
+define([<MF_VAR_SET_STRING>],[<
+{ size_t off;
+ if ($2)
+ MF_COPY_STRING(off, $2);
+ else
+ off = 0;
+ MF_VAR_REF($1, off); }
+>])
dnl MF_VAR_INC(name) - Increment the value of the global variable NAME
dnl

Return to:

Send suggestions and report system problems to the System administrator.