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) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29#include <stdio.h>
30
31#include <fcode/private.h>
32#include <fcode/log.h>
33
34void
35do_run(fcode_env_t *env, int next)
36{
37	token_t target, indirect;
38	void (*fn)(fcode_env_t *env);
39	int debug_state = current_debug_state(env);
40	extern void do_memory_watch(fcode_env_t *env);
41
42	for (; ; ) {
43		if (next) {
44			DEBUGF(NEXT_VITALS, output_vitals(env);
45			    log_message(MSG_FC_DEBUG, "\n"));
46			CHECK_INTERRUPT;
47			if (IP == NULL)
48				break;
49			WA = (token_t *) *IP;
50			IP++;
51		}
52		check_for_debug_entry(env);
53		indirect = *WA;
54		if (indirect & 1) {
55			target = indirect & ~1;
56			target = *((token_t *)target);
57		} else
58			target = indirect;
59		fn = (void (*)(fcode_env_t *)) target;
60		if (do_exec_debug(env, (void *)fn))
61			break;
62		if (indirect & 1) {
63			PUSH(DS, (fstack_t) (WA+1));
64			WA = (token_t *) target;
65		}
66		WA++;
67		fn(env);
68		check_vitals(env);
69		check_for_debug_exit(env);
70		do_memory_watch(env);
71		next = 1;
72	}
73	clear_debug_state(env, debug_state);
74}
75
76void
77do_semi(fcode_env_t *env)
78{
79	CHECK_RETURN_DEPTH(env, 1, ";");
80	check_semi_debug_exit(env);
81	IP = (token_t *) POP(RS);
82}
83
84void
85do_colon(fcode_env_t *env)
86{
87	PUSH(RS, (fstack_t) IP);
88	IP = WA;
89}
90
91void
92do_alias(fcode_env_t *env)
93{
94	token_t *ip;
95
96	ip = IP;
97	IP = 0;
98	WA = (token_t *) *WA;
99	do_run(env, 0);
100	IP = ip;
101}
102
103void
104execute(fcode_env_t *env)
105{
106	token_t *ip, *wa;
107
108	/*
109	 * In order to ensure that only this token executes we
110	 * force IP to zero after stashing it, then when the stack
111	 * unwinds (do_run returns) we can restore the old value.
112	 */
113	CHECK_DEPTH(env, 1, "execute");
114	ip = IP;
115	wa = WA;
116	IP = 0;
117	WA = (token_t *) POP(DS);
118	do_run(env, 0);
119	IP = ip;
120	WA = wa;
121}
122