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
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]
23 * Copyright (c) 2000 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
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.
42 value_fetch(fcode_env_t
*env
)
46 CHECK_DEPTH(env
, 1, "value_fetch");
47 addr
= (variable_t
*)POP(DS
);
48 PUSH(DS
, (variable_t
)*addr
);
52 value_store(fcode_env_t
*env
)
56 CHECK_DEPTH(env
, 1, "value_store");
57 addr
= (variable_t
*)POP(DS
);
58 *addr
= (variable_t
)POP(DS
);
62 get_internal_address(fcode_env_t
*env
)
66 CHECK_DEPTH(env
, 1, "get_internal_address");
69 return ((uchar_t
*)env
+ *ptr
);
70 return ((uchar_t
*)MYSELF
- *ptr
);
74 internal_env_fetch(fcode_env_t
*env
)
78 CHECK_DEPTH(env
, 1, "internal_env_fetch");
79 iptr
= (instance_t
**)get_internal_address(env
);
80 PUSH(DS
, (fstack_t
)(*iptr
));
84 internal_env_store(fcode_env_t
*env
)
88 CHECK_DEPTH(env
, 2, "internal_env_store");
89 iptr
= (instance_t
**)get_internal_address(env
);
90 *iptr
= (instance_t
*)POP(DS
);
94 internal_env_addr(fcode_env_t
*env
)
98 CHECK_DEPTH(env
, 1, "internal_env_addr");
99 d
= (fstack_t
)get_internal_address(env
);
104 do_buffer_data(fcode_env_t
*env
, token_t
*d
, int instance
)
106 if (!*d
) { /* check if buffer not alloc'ed yet */
112 n
= TOKEN_ROUNDUP(d
[1]);
113 buf
= alloc_instance_data(env
, UINIT_DATA
, n
, &off
);
114 memset(buf
, 0, d
[1]);
116 buf
= (token_t
*)HERE
;
117 set_here(env
, HERE
+ d
[1], "do_buffer_data");
125 ibuffer_init(fcode_env_t
*env
)
129 d
= get_instance_address(env
);
130 do_buffer_data(env
, d
, 1);
134 buffer_init(fcode_env_t
*env
)
138 CHECK_DEPTH(env
, 1, "buffer_init");
139 d
= (token_t
*)POP(DS
);
140 do_buffer_data(env
, d
, 0);
144 do_defer(fcode_env_t
*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]);
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]);
184 if (p
[0] == (token_t
)&do_default_action
) {
187 d
= (fstack_t
)p
[action
+2];
192 log_message(MSG_WARN
, "run_action: acf: %p/%p not default action\n",
198 do_default_action(fcode_env_t
*env
)
202 CHECK_DEPTH(env
, 1, "do_default_action");
204 (void) run_action(env
, (a
-1), 0);
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);
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
);
228 actions(fcode_env_t
*env
)
233 token_roundup(env
, "actions");
235 *d
++ = (token_t
)&do_default_action
;
238 env
->num_actions
= n
;
239 env
->action_count
= 0;
242 set_here(env
, (uchar_t
*)d
, "actions");
246 install_actions(fcode_env_t
*env
, token_t
*table
)
251 dptr
= (acf_t
*)LINK_TO_ACF(env
->lastlink
);
253 p
-= (sizeof (token_t
) + sizeof (acf_t
));
254 *dptr
= (acf_t
)(p
| 1);
258 use_actions(fcode_env_t
*env
)
261 TODO
; /* use-actions in compile state. */
263 install_actions(env
, env
->action_ptr
);
268 perform_action(fcode_env_t
*env
)
273 CHECK_DEPTH(env
, 2, "perform_action");
276 PUSH(DS
, (fstack_t
)ACF_TO_BODY(a
));
278 if (run_action(env
, a
, n
)) {
279 system_message(env
, "Bad Object action");
284 define_actions(fcode_env_t
*env
, int n
, token_t
*array
)
288 PUSH(DS
, (fstack_t
)n
);
294 COMPILE_TOKEN(&array
[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.
309 set_internal_value_actions(fcode_env_t
*env
)
311 ASSERT(value_actions
[2]);
312 install_actions(env
, value_actions
[2]);
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
]);
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]);
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]);
342 do_get(fcode_env_t
*env
)
349 do_set(fcode_env_t
*env
)
356 do_addr(fcode_env_t
*env
)
363 dump_actions(fcode_env_t
*env
)
366 for (i
= 0; i
< NUM_DEFAULT_ACTIONS
; i
++) {
367 log_message(MSG_INFO
, "Action Set: %d = %p\n", i
,
378 fcode_env_t
*env
= initial_env
;
384 for (i
= 0; i
< NUM_DEFAULT_ACTIONS
; i
++) {
385 define_actions(env
, 3, value_defines
[i
]);
386 value_actions
[i
] = env
->action_ptr
;
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
);