diff options
Diffstat (limited to 'usr/src/lib/efcode/engine/interface.c')
-rw-r--r-- | usr/src/lib/efcode/engine/interface.c | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/usr/src/lib/efcode/engine/interface.c b/usr/src/lib/efcode/engine/interface.c new file mode 100644 index 0000000000..31f0cc9e91 --- /dev/null +++ b/usr/src/lib/efcode/engine/interface.c @@ -0,0 +1,273 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2000 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include <fcode/private.h> +#include <fcode/log.h> + +/* + * the external start point for this goo + */ + +void +push_ds(fcode_env_t *env, fstack_t d) +{ + PUSH(DS, d); +} + +fstack_t +pop_ds(fcode_env_t *env) +{ + return (POP(DS)); +} + +void +push_rs(fcode_env_t *env, fstack_t d) +{ + PUSH(RS, d); +} + +fstack_t +pop_rs(fcode_env_t *env) +{ + return (POP(RS)); +} + +/* + * Pushes a C string on the stack. + */ +void +push_a_string(fcode_env_t *env, char *str) +{ + if (str) { + PUSH(DS, (fstack_t)str); + PUSH(DS, strlen(str)); + } else { + PUSH(DS, 0); + PUSH(DS, 0); + } +} + +/* + * Pops a (potentially null) string off the stack. + */ +char * +pop_a_string(fcode_env_t *env, int *lenp) +{ + int len; + char *str; + + len = POP(DS); + str = (char *)POP(DS); + if (len == 0) + str = NULL; + else if (str == NULL) + len = 0; + if (lenp) + *lenp = len; + return (str); +} + +/* + * Pops & strdup's a string off the stack, handles NULL strings. + */ +char * +pop_a_duped_string(fcode_env_t *env, int *lenp) +{ + char *str; + + str = pop_a_string(env, lenp); + if (str) + return (STRDUP(str)); + return (NULL); +} + +/* + * Push Forth Double type. + */ +void +push_double(fcode_env_t *env, dforth_t d) +{ + fstack_t lo, hi; + + lo = DFORTH_LO(d); + hi = DFORTH_HI(d); + PUSH(DS, lo); + PUSH(DS, hi); +} + +/* + * Pop Forth Double type. + */ +dforth_t +pop_double(fcode_env_t *env) +{ + fstack_t lo, hi; + + hi = POP(DS); + lo = POP(DS); + return (MAKE_DFORTH(hi, lo)); +} + +/* + * Peek at top of stack Forth Double type. + */ +dforth_t +peek_double(fcode_env_t *env) +{ + dforth_t a; + + a = pop_double(env); + push_double(env, a); + return (a); +} + +void +run_fcode(fcode_env_t *env, uchar_t *buff, int len) +{ + int i; + + /* + * Really just checking to see if buff is all ascii characters. + * Fcode normally starts with 0xfd, so for fcode, this should be + * a fast check. + */ + for (i = 0; i < len; i++) + if (buff[i] >= 0x80) + break; + PUSH(DS, (fstack_t)buff); + if (i < len) { + /* Non-ascii found, probably Fcode */ + PUSH(DS, (fstack_t)1); + byte_load(env); + } else { + /* All ascii found, probably ascii */ + PUSH(DS, len); + fevaluate(env); + } +} + +void +run_fcode_from_file(fcode_env_t *env, char *fname, int aout_flag) +{ + uchar_t *p; + int len; + + push_a_string(env, fname); + load_file(env); + len = POP(DS); + p = (uchar_t *)POP(DS); + if (aout_flag) { + p += 0x20; + len -= 0x20; + } + run_fcode(env, p, len); +} + +fcode_env_t * +clone_environment(fcode_env_t *src, void *private) +{ + fcode_env_t *env; + + if (!src) { + src = initial_env; + src->private = private; + return (src); + } + +#if 0 + src->private = private; + if (src->my_self || src->state) { + log_message(MSG_WARN, "Can't clone an active instance or" + " compile state!\n"); + return (NULL); + } + + log_message(MSG_WARN, "Warning: Device-tree state is shared!\n"); +#endif + + env = MALLOC(sizeof (fcode_env_t)); + memcpy(env, src, sizeof (fcode_env_t)); + +#if 0 + env->table = MALLOC((MAX_FCODE + 1) * sizeof (fcode_token)); + memcpy(env->table, src->table, (MAX_FCODE + 1) * sizeof (fcode_token)); + + /* + * Note that cloning the dictionary doesn't make sense unless the + * ptrs + XT's in the dictionary are relative to BASE. + */ + env->base = MALLOC(dict_size); + memcpy(env->base, src->base, dict_size); + + env->here = src->base - (uchar_t *)src + env->base; +#endif + + env->ds0 = MALLOC(stack_size * sizeof (fstack_t)); + memcpy(env->ds0, src->ds0, stack_size * sizeof (fstack_t)); + env->ds = src->ds - src->ds0 + env->ds0; + + env->rs0 = MALLOC(stack_size * sizeof (fstack_t)); + memcpy(env->rs0, src->rs0, stack_size * sizeof (fstack_t)); + env->rs = src->rs - src->rs0 + env->rs0; + + env->order = MALLOC(MAX_ORDER * sizeof (token_t)); + memcpy(env->order, src->order, MAX_ORDER * sizeof (token_t)); + + env->input = MALLOC(sizeof (input_typ)); + + env->catch_frame = 0; + + IP = 0; + + return (env); +} + +void +destroy_environment(fcode_env_t *env) +{ + FREE(env->input); + FREE(env->order); + FREE(env->ds0); + FREE(env->rs0); +#if 0 + FREE(env->base); + FREE(env->table); +#endif + FREE(env); + + if (env == initial_env) { + /* This call only happens internally */ + + initial_env = NULL; + /* You had better not exercise the engine anymore! */ + } +} |