/* * 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 #include #include #include #include /* * 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! */ } }