summaryrefslogtreecommitdiff
path: root/usr/src/lib/efcode/engine/extend.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/efcode/engine/extend.c')
-rw-r--r--usr/src/lib/efcode/engine/extend.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/usr/src/lib/efcode/engine/extend.c b/usr/src/lib/efcode/engine/extend.c
new file mode 100644
index 0000000000..9e631012b2
--- /dev/null
+++ b/usr/src/lib/efcode/engine/extend.c
@@ -0,0 +1,147 @@
+/*
+ * 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 <sys/shm.h>
+#include <dlfcn.h>
+#include <fcode/private.h>
+
+static void
+do_dlopen(fcode_env_t *env)
+{
+ char *name;
+ int mode;
+ void *pl;
+
+ mode = POP(DS);
+ name = pop_a_string(env, NULL);
+ pl = dlopen(name, mode);
+ PUSH(DS, (fstack_t)pl);
+}
+
+static void
+do_extend(fcode_env_t *env)
+{
+ parse_word(env);
+ PUSH(DS, (fstack_t)RTLD_NOW);
+ do_dlopen(env);
+ drop(env);
+}
+
+static void
+do_dlclose(fcode_env_t *env)
+{
+ void *pl = (void *)POP(DS);
+ dlclose(pl);
+}
+
+static void
+do_dlsym(fcode_env_t *env)
+{
+ char *name;
+ fstack_t d;
+
+ name = pop_a_string(env, NULL);
+ d = POP(DS);
+ d = (fstack_t)dlsym((void *) d, name);
+ PUSH(DS, d);
+}
+
+static void
+do_dlexec(fcode_env_t *env)
+{
+ int args;
+ fstack_t a, b, c, d;
+ fstack_t (*fn0)(void);
+ fstack_t (*fn1)(fstack_t);
+ fstack_t (*fn2)(fstack_t, fstack_t);
+ fstack_t (*fn3)(fstack_t, fstack_t, fstack_t);
+ fstack_t (*fn4)(fstack_t, fstack_t, fstack_t, fstack_t);
+
+ args = POP(DS);
+ a = POP(DS);
+ switch (args) {
+
+ case 0:
+ fn0 = (fstack_t (*)(void)) a;
+ a = fn0();
+ PUSH(DS, a);
+ break;
+
+ case 1:
+ fn1 = (fstack_t (*)(fstack_t)) a;
+ a = POP(DS);
+ a = fn1(a);
+ PUSH(DS, a);
+ break;
+
+ case 2:
+ fn2 = (fstack_t (*)(fstack_t, fstack_t))a;
+ a = POP(DS);
+ b = POP(DS);
+ a = fn2(a, b);
+ PUSH(DS, a);
+ break;
+
+ case 3:
+ fn3 = (fstack_t (*)(fstack_t, fstack_t, fstack_t))a;
+ a = POP(DS);
+ b = POP(DS);
+ c = POP(DS);
+ a = fn3(a, b, c);
+ PUSH(DS, a);
+ break;
+
+ case 4:
+ fn4 = (fstack_t (*)(fstack_t, fstack_t, fstack_t, fstack_t))a;
+ a = POP(DS);
+ b = POP(DS);
+ c = POP(DS);
+ d = POP(DS);
+ a = fn4(a, b, c, d);
+ PUSH(DS, a);
+ break;
+ }
+}
+
+#pragma init(_init)
+
+static void
+_init(void)
+{
+ fcode_env_t *env = initial_env;
+
+ ASSERT(env);
+ NOTICE;
+
+ FORTH(0, "dl-open", do_dlopen);
+ FORTH(0, "dl-close", do_dlclose);
+ FORTH(0, "dl-sym", do_dlsym);
+ FORTH(0, "dl-exec", do_dlexec);
+ FORTH(IMMEDIATE, "extend-from", do_extend);
+}