summaryrefslogtreecommitdiff
path: root/usr/src/lib/efcode/engine/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/efcode/engine/interface.c')
-rw-r--r--usr/src/lib/efcode/engine/interface.c273
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! */
+ }
+}