dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / efcode / engine / actions.c
blob11fb96c36356e16ed38bac90a8260312f11a7577
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
23 * Copyright (c) 2000 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <stdio.h>
30 #include <string.h>
32 #include <fcode/private.h>
33 #include <fcode/log.h>
35 #define NUM_DEFAULT_ACTIONS 7
38 * value_fetch and value_store are the same as "fetch" and "store", but
39 * we'll leave them implemented here for now.
41 static void
42 value_fetch(fcode_env_t *env)
44 variable_t *addr;
46 CHECK_DEPTH(env, 1, "value_fetch");
47 addr = (variable_t *)POP(DS);
48 PUSH(DS, (variable_t)*addr);
51 static void
52 value_store(fcode_env_t *env)
54 variable_t *addr;
56 CHECK_DEPTH(env, 1, "value_store");
57 addr = (variable_t *)POP(DS);
58 *addr = (variable_t)POP(DS);
61 void *
62 get_internal_address(fcode_env_t *env)
64 int *ptr;
66 CHECK_DEPTH(env, 1, "get_internal_address");
67 ptr = (int *)POP(DS);
68 if (*ptr > 0)
69 return ((uchar_t *)env + *ptr);
70 return ((uchar_t *)MYSELF - *ptr);
73 void
74 internal_env_fetch(fcode_env_t *env)
76 instance_t **iptr;
78 CHECK_DEPTH(env, 1, "internal_env_fetch");
79 iptr = (instance_t **)get_internal_address(env);
80 PUSH(DS, (fstack_t)(*iptr));
83 void
84 internal_env_store(fcode_env_t *env)
86 instance_t **iptr;
88 CHECK_DEPTH(env, 2, "internal_env_store");
89 iptr = (instance_t **)get_internal_address(env);
90 *iptr = (instance_t *)POP(DS);
93 void
94 internal_env_addr(fcode_env_t *env)
96 fstack_t d;
98 CHECK_DEPTH(env, 1, "internal_env_addr");
99 d = (fstack_t)get_internal_address(env);
100 PUSH(DS, d);
103 void
104 do_buffer_data(fcode_env_t *env, token_t *d, int instance)
106 if (!*d) { /* check if buffer not alloc'ed yet */
107 token_t *buf;
109 if (instance) {
110 int n, off;
112 n = TOKEN_ROUNDUP(d[1]);
113 buf = alloc_instance_data(env, UINIT_DATA, n, &off);
114 memset(buf, 0, d[1]);
115 } else {
116 buf = (token_t *)HERE;
117 set_here(env, HERE + d[1], "do_buffer_data");
119 *d = (token_t)buf;
121 PUSH(DS, *d);
124 void
125 ibuffer_init(fcode_env_t *env)
127 token_t *d;
129 d = get_instance_address(env);
130 do_buffer_data(env, d, 1);
133 void
134 buffer_init(fcode_env_t *env)
136 token_t *d;
138 CHECK_DEPTH(env, 1, "buffer_init");
139 d = (token_t *)POP(DS);
140 do_buffer_data(env, d, 0);
143 void
144 do_defer(fcode_env_t *env)
146 fetch(env);
147 execute(env);
150 token_t *value_actions[NUM_DEFAULT_ACTIONS];
151 token_t value_defines[NUM_DEFAULT_ACTIONS][3] = {
152 { (token_t)&value_fetch, (token_t)&value_store, (token_t)&noop },
153 { (token_t)&fetch_instance_data, (token_t)&set_instance_data,
154 (token_t)&address_instance_data },
155 { (token_t)&internal_env_fetch, (token_t)&internal_env_store,
156 (token_t)&internal_env_addr },
157 { (token_t)&do_defer, (token_t)&store, (token_t)&noop },
158 { (token_t)&idefer_exec, (token_t)&set_instance_data,
159 (token_t)&address_instance_data },
160 { (token_t)&buffer_init, (token_t)&two_drop, (token_t)&noop, },
161 { (token_t)&ibuffer_init, (token_t)&two_drop,
162 (token_t)&address_instance_data }
166 run_action(fcode_env_t *env, acf_t acf, int action)
168 token_t *p = (token_t *)acf;
170 if ((p[0] & 1) == 0) {
171 log_message(MSG_WARN, "run_action: acf: %p @acf: %p not"
172 " indirect\n", acf, p[0]);
173 return (1);
176 p = (token_t *)(p[0] & ~1);
178 if (action >= p[1] || action < 0) {
179 log_message(MSG_WARN, "run_action: acf: %p action: %d"
180 " out of range: 0-%d\n", acf, action, (int)p[1]);
181 return (1);
184 if (p[0] == (token_t)&do_default_action) {
185 fstack_t d;
187 d = (fstack_t)p[action+2];
188 PUSH(DS, d);
189 execute(env);
190 return (0);
192 log_message(MSG_WARN, "run_action: acf: %p/%p not default action\n",
193 acf, p[0]);
194 return (1);
197 void
198 do_default_action(fcode_env_t *env)
200 acf_t a;
202 CHECK_DEPTH(env, 1, "do_default_action");
203 a = (acf_t)TOS;
204 (void) run_action(env, (a-1), 0);
207 void
208 do_set_action(fcode_env_t *env)
210 acf_t a = (acf_t)TOS;
212 CHECK_DEPTH(env, 1, "do_set_action");
213 TOS += sizeof (acf_t);
214 (void) run_action(env, a, 1);
217 void
218 action_colon(fcode_env_t *env)
220 token_roundup(env, "action_colon");
221 env->action_ptr[env->action_count] = (token_t)HERE;
222 COMPILE_TOKEN(&do_colon);
223 env->action_count++;
224 env->state |= 1;
227 void
228 actions(fcode_env_t *env)
230 int n;
231 token_t *d;
233 token_roundup(env, "actions");
234 d = (token_t *)HERE;
235 *d++ = (token_t)&do_default_action;
236 n = (int)POP(DS);
237 *d++ = n;
238 env->num_actions = n;
239 env->action_count = 0;
240 env->action_ptr = d;
241 d += n;
242 set_here(env, (uchar_t *)d, "actions");
245 void
246 install_actions(fcode_env_t *env, token_t *table)
248 acf_t *dptr;
249 token_t p;
251 dptr = (acf_t *)LINK_TO_ACF(env->lastlink);
252 p = (token_t)table;
253 p -= (sizeof (token_t) + sizeof (acf_t));
254 *dptr = (acf_t)(p | 1);
257 void
258 use_actions(fcode_env_t *env)
260 if (env->state) {
261 TODO; /* use-actions in compile state. */
262 } else {
263 install_actions(env, env->action_ptr);
267 void
268 perform_action(fcode_env_t *env)
270 int n;
271 acf_t a;
273 CHECK_DEPTH(env, 2, "perform_action");
274 n = POP(DS);
275 a = (acf_t)POP(DS);
276 PUSH(DS, (fstack_t)ACF_TO_BODY(a));
278 if (run_action(env, a, n)) {
279 system_message(env, "Bad Object action");
283 void
284 define_actions(fcode_env_t *env, int n, token_t *array)
286 int a;
288 PUSH(DS, (fstack_t)n);
289 actions(env);
291 a = 0;
292 while (n--) {
293 action_colon(env);
294 COMPILE_TOKEN(&array[a]);
295 env->state |= 8;
296 semi(env);
297 a++;
302 * This is for things like my-self which have meaning to the
303 * forth engine but I don't want to turn them into standard forth values
304 * that would make the 'C' variables hard to understand, instead these
305 * 'global' state variables will act directly upon the native 'C' structures.
308 void
309 set_internal_value_actions(fcode_env_t *env)
311 ASSERT(value_actions[2]);
312 install_actions(env, value_actions[2]);
315 void
316 set_value_actions(fcode_env_t *env, int which)
318 ASSERT((which == 0) || (which == 1));
319 ASSERT(value_actions[which]);
320 install_actions(env, value_actions[which]);
323 void
324 set_defer_actions(fcode_env_t *env, int which)
326 ASSERT((which == 0) || (which == 1));
327 ASSERT(value_actions[which+3]);
328 install_actions(env, value_actions[which+3]);
331 void
332 set_buffer_actions(fcode_env_t *env, int which)
334 ASSERT((which == 0) || (which == 1));
335 ASSERT(value_actions[which+5]);
336 install_actions(env, value_actions[which+5]);
339 #if defined(DEBUG)
341 void
342 do_get(fcode_env_t *env)
344 PUSH(DS, 0);
345 perform_action(env);
348 void
349 do_set(fcode_env_t *env)
351 PUSH(DS, 1);
352 perform_action(env);
355 void
356 do_addr(fcode_env_t *env)
358 PUSH(DS, 2);
359 perform_action(env);
362 void
363 dump_actions(fcode_env_t *env)
365 int i;
366 for (i = 0; i < NUM_DEFAULT_ACTIONS; i++) {
367 log_message(MSG_INFO, "Action Set: %d = %p\n", i,
368 value_actions[i]);
371 #endif /* DEBUG */
373 #pragma init(_init)
375 static void
376 _init(void)
378 fcode_env_t *env = initial_env;
379 int i;
381 ASSERT(env);
382 NOTICE;
384 for (i = 0; i < NUM_DEFAULT_ACTIONS; i++) {
385 define_actions(env, 3, value_defines[i]);
386 value_actions[i] = env->action_ptr;
389 #if defined(DEBUG)
390 FORTH(0, "get", do_get);
391 FORTH(0, "set", do_set);
392 FORTH(0, "addr", do_addr);
393 FORTH(0, "dump-actions", dump_actions);
394 FORTH(IMMEDIATE, "actions", actions);
395 FORTH(IMMEDIATE, "use-actions", use_actions);
396 FORTH(IMMEDIATE, "action:", action_colon);
397 FORTH(0, "perform-action", perform_action);
398 #endif /* DEBUG */