1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 2000 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdio.h> 30 #include <string.h> 31 #include <stdlib.h> 32 33 #include <fcode/private.h> 34 #include <fcode/log.h> 35 36 /* 37 * the external start point for this goo 38 */ 39 40 void 41 push_ds(fcode_env_t *env, fstack_t d) 42 { 43 PUSH(DS, d); 44 } 45 46 fstack_t 47 pop_ds(fcode_env_t *env) 48 { 49 return (POP(DS)); 50 } 51 52 void 53 push_rs(fcode_env_t *env, fstack_t d) 54 { 55 PUSH(RS, d); 56 } 57 58 fstack_t 59 pop_rs(fcode_env_t *env) 60 { 61 return (POP(RS)); 62 } 63 64 /* 65 * Pushes a C string on the stack. 66 */ 67 void 68 push_a_string(fcode_env_t *env, char *str) 69 { 70 if (str) { 71 PUSH(DS, (fstack_t)str); 72 PUSH(DS, strlen(str)); 73 } else { 74 PUSH(DS, 0); 75 PUSH(DS, 0); 76 } 77 } 78 79 /* 80 * Pops a (potentially null) string off the stack. 81 */ 82 char * 83 pop_a_string(fcode_env_t *env, int *lenp) 84 { 85 int len; 86 char *str; 87 88 len = POP(DS); 89 str = (char *)POP(DS); 90 if (len == 0) 91 str = NULL; 92 else if (str == NULL) 93 len = 0; 94 if (lenp) 95 *lenp = len; 96 return (str); 97 } 98 99 /* 100 * Pops & strdup's a string off the stack, handles NULL strings. 101 */ 102 char * 103 pop_a_duped_string(fcode_env_t *env, int *lenp) 104 { 105 char *str; 106 107 str = pop_a_string(env, lenp); 108 if (str) 109 return (STRDUP(str)); 110 return (NULL); 111 } 112 113 /* 114 * Push Forth Double type. 115 */ 116 void 117 push_double(fcode_env_t *env, dforth_t d) 118 { 119 fstack_t lo, hi; 120 121 lo = DFORTH_LO(d); 122 hi = DFORTH_HI(d); 123 PUSH(DS, lo); 124 PUSH(DS, hi); 125 } 126 127 /* 128 * Pop Forth Double type. 129 */ 130 dforth_t 131 pop_double(fcode_env_t *env) 132 { 133 fstack_t lo, hi; 134 135 hi = POP(DS); 136 lo = POP(DS); 137 return (MAKE_DFORTH(hi, lo)); 138 } 139 140 /* 141 * Peek at top of stack Forth Double type. 142 */ 143 dforth_t 144 peek_double(fcode_env_t *env) 145 { 146 dforth_t a; 147 148 a = pop_double(env); 149 push_double(env, a); 150 return (a); 151 } 152 153 void 154 run_fcode(fcode_env_t *env, uchar_t *buff, int len) 155 { 156 int i; 157 158 /* 159 * Really just checking to see if buff is all ascii characters. 160 * Fcode normally starts with 0xfd, so for fcode, this should be 161 * a fast check. 162 */ 163 for (i = 0; i < len; i++) 164 if (buff[i] >= 0x80) 165 break; 166 PUSH(DS, (fstack_t)buff); 167 if (i < len) { 168 /* Non-ascii found, probably Fcode */ 169 PUSH(DS, (fstack_t)1); 170 byte_load(env); 171 } else { 172 /* All ascii found, probably ascii */ 173 PUSH(DS, len); 174 fevaluate(env); 175 } 176 } 177 178 void 179 run_fcode_from_file(fcode_env_t *env, char *fname, int aout_flag) 180 { 181 uchar_t *p; 182 int len; 183 184 push_a_string(env, fname); 185 load_file(env); 186 len = POP(DS); 187 p = (uchar_t *)POP(DS); 188 if (aout_flag) { 189 p += 0x20; 190 len -= 0x20; 191 } 192 run_fcode(env, p, len); 193 } 194 195 fcode_env_t * 196 clone_environment(fcode_env_t *src, void *private) 197 { 198 fcode_env_t *env; 199 200 if (!src) { 201 src = initial_env; 202 src->private = private; 203 return (src); 204 } 205 206 #if 0 207 src->private = private; 208 if (src->my_self || src->state) { 209 log_message(MSG_WARN, "Can't clone an active instance or" 210 " compile state!\n"); 211 return (NULL); 212 } 213 214 log_message(MSG_WARN, "Warning: Device-tree state is shared!\n"); 215 #endif 216 217 env = MALLOC(sizeof (fcode_env_t)); 218 memcpy(env, src, sizeof (fcode_env_t)); 219 220 #if 0 221 env->table = MALLOC((MAX_FCODE + 1) * sizeof (fcode_token)); 222 memcpy(env->table, src->table, (MAX_FCODE + 1) * sizeof (fcode_token)); 223 224 /* 225 * Note that cloning the dictionary doesn't make sense unless the 226 * ptrs + XT's in the dictionary are relative to BASE. 227 */ 228 env->base = MALLOC(dict_size); 229 memcpy(env->base, src->base, dict_size); 230 231 env->here = src->base - (uchar_t *)src + env->base; 232 #endif 233 234 env->ds0 = MALLOC(stack_size * sizeof (fstack_t)); 235 memcpy(env->ds0, src->ds0, stack_size * sizeof (fstack_t)); 236 env->ds = src->ds - src->ds0 + env->ds0; 237 238 env->rs0 = MALLOC(stack_size * sizeof (fstack_t)); 239 memcpy(env->rs0, src->rs0, stack_size * sizeof (fstack_t)); 240 env->rs = src->rs - src->rs0 + env->rs0; 241 242 env->order = MALLOC(MAX_ORDER * sizeof (token_t)); 243 memcpy(env->order, src->order, MAX_ORDER * sizeof (token_t)); 244 245 env->input = MALLOC(sizeof (input_typ)); 246 247 env->catch_frame = 0; 248 249 IP = 0; 250 251 return (env); 252 } 253 254 void 255 destroy_environment(fcode_env_t *env) 256 { 257 FREE(env->input); 258 FREE(env->order); 259 FREE(env->ds0); 260 FREE(env->rs0); 261 #if 0 262 FREE(env->base); 263 FREE(env->table); 264 #endif 265 FREE(env); 266 267 if (env == initial_env) { 268 /* This call only happens internally */ 269 270 initial_env = NULL; 271 /* You had better not exercise the engine anymore! */ 272 } 273 } 274