1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright (c) 2000 by Sun Microsystems, Inc.
24*0Sstevel@tonic-gate * All rights reserved.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate #include <stdio.h>
30*0Sstevel@tonic-gate #include <stdlib.h>
31*0Sstevel@tonic-gate #include <string.h>
32*0Sstevel@tonic-gate #include <ctype.h>
33*0Sstevel@tonic-gate
34*0Sstevel@tonic-gate #include <fcode/private.h>
35*0Sstevel@tonic-gate #include <fcode/log.h>
36*0Sstevel@tonic-gate
37*0Sstevel@tonic-gate int fcode_impl_count = 0;
38*0Sstevel@tonic-gate
39*0Sstevel@tonic-gate void (*crash_ptr)(fcode_env_t *env) = do_crash;
40*0Sstevel@tonic-gate
41*0Sstevel@tonic-gate uchar_t
next_bytecode(fcode_env_t * env)42*0Sstevel@tonic-gate next_bytecode(fcode_env_t *env)
43*0Sstevel@tonic-gate {
44*0Sstevel@tonic-gate uchar_t byte;
45*0Sstevel@tonic-gate
46*0Sstevel@tonic-gate byte = *env->fcode_ptr;
47*0Sstevel@tonic-gate env->fcode_ptr += env->fcode_incr;
48*0Sstevel@tonic-gate return (byte);
49*0Sstevel@tonic-gate }
50*0Sstevel@tonic-gate
51*0Sstevel@tonic-gate ushort_t
get_next_token(fcode_env_t * env)52*0Sstevel@tonic-gate get_next_token(fcode_env_t *env)
53*0Sstevel@tonic-gate {
54*0Sstevel@tonic-gate ushort_t token = next_bytecode(env);
55*0Sstevel@tonic-gate if ((token) && (token < 0x10)) {
56*0Sstevel@tonic-gate token = (token << 8) | next_bytecode(env);
57*0Sstevel@tonic-gate }
58*0Sstevel@tonic-gate env->last_fcode = token;
59*0Sstevel@tonic-gate return (token);
60*0Sstevel@tonic-gate }
61*0Sstevel@tonic-gate
62*0Sstevel@tonic-gate ushort_t
get_short(fcode_env_t * env)63*0Sstevel@tonic-gate get_short(fcode_env_t *env)
64*0Sstevel@tonic-gate {
65*0Sstevel@tonic-gate ushort_t u;
66*0Sstevel@tonic-gate
67*0Sstevel@tonic-gate /*
68*0Sstevel@tonic-gate * Logical or DOES NOT guarantee left to right evaluation...
69*0Sstevel@tonic-gate */
70*0Sstevel@tonic-gate u = next_bytecode(env) << 8;
71*0Sstevel@tonic-gate return (u | next_bytecode(env));
72*0Sstevel@tonic-gate }
73*0Sstevel@tonic-gate
74*0Sstevel@tonic-gate uint_t
get_int(fcode_env_t * env)75*0Sstevel@tonic-gate get_int(fcode_env_t *env)
76*0Sstevel@tonic-gate {
77*0Sstevel@tonic-gate uint_t u;
78*0Sstevel@tonic-gate
79*0Sstevel@tonic-gate /*
80*0Sstevel@tonic-gate * Logical or DOES NOT guarantee left to right evaluation...
81*0Sstevel@tonic-gate */
82*0Sstevel@tonic-gate u = get_short(env) << 16;
83*0Sstevel@tonic-gate return (u | get_short(env));
84*0Sstevel@tonic-gate }
85*0Sstevel@tonic-gate
86*0Sstevel@tonic-gate void
expose_acf(fcode_env_t * env,char * name)87*0Sstevel@tonic-gate expose_acf(fcode_env_t *env, char *name)
88*0Sstevel@tonic-gate {
89*0Sstevel@tonic-gate if (name == NULL)
90*0Sstevel@tonic-gate name = "<unknown>";
91*0Sstevel@tonic-gate EXPOSE_ACF;
92*0Sstevel@tonic-gate debug_msg(DEBUG_CONTEXT, "CONTEXT:expose_acf: acf: %p/'%s' %p\n",
93*0Sstevel@tonic-gate LINK_TO_ACF(env->lastlink), name, env->current);
94*0Sstevel@tonic-gate }
95*0Sstevel@tonic-gate
96*0Sstevel@tonic-gate void
do_code(fcode_env_t * env,int token,char * name,void (* fn)(fcode_env_t *))97*0Sstevel@tonic-gate do_code(fcode_env_t *env, int token, char *name, void (*fn)(fcode_env_t *))
98*0Sstevel@tonic-gate {
99*0Sstevel@tonic-gate env->table[token].name = name;
100*0Sstevel@tonic-gate if (fn == NULL) {
101*0Sstevel@tonic-gate env->table[token].apf = NULL;
102*0Sstevel@tonic-gate env->table[token].name = name;
103*0Sstevel@tonic-gate } else {
104*0Sstevel@tonic-gate header(env, name, strlen(name), 0);
105*0Sstevel@tonic-gate env->table[token].apf = (acf_t)HERE;
106*0Sstevel@tonic-gate COMPILE_TOKEN(fn);
107*0Sstevel@tonic-gate expose_acf(env, name);
108*0Sstevel@tonic-gate }
109*0Sstevel@tonic-gate }
110*0Sstevel@tonic-gate
111*0Sstevel@tonic-gate void
define_word(fcode_env_t * env,int flag,char * name,void (* fn)(fcode_env_t *))112*0Sstevel@tonic-gate define_word(fcode_env_t *env, int flag, char *name, void (*fn)(fcode_env_t *))
113*0Sstevel@tonic-gate {
114*0Sstevel@tonic-gate header(env, name, strlen(name), flag);
115*0Sstevel@tonic-gate COMPILE_TOKEN(fn);
116*0Sstevel@tonic-gate expose_acf(env, name);
117*0Sstevel@tonic-gate }
118*0Sstevel@tonic-gate
119*0Sstevel@tonic-gate void
end0(fcode_env_t * env)120*0Sstevel@tonic-gate end0(fcode_env_t *env)
121*0Sstevel@tonic-gate {
122*0Sstevel@tonic-gate env->interpretting = 0;
123*0Sstevel@tonic-gate }
124*0Sstevel@tonic-gate
125*0Sstevel@tonic-gate static void
end1(fcode_env_t * env)126*0Sstevel@tonic-gate end1(fcode_env_t *env)
127*0Sstevel@tonic-gate {
128*0Sstevel@tonic-gate env->interpretting = 0;
129*0Sstevel@tonic-gate }
130*0Sstevel@tonic-gate
131*0Sstevel@tonic-gate void
blit(fcode_env_t * env)132*0Sstevel@tonic-gate blit(fcode_env_t *env)
133*0Sstevel@tonic-gate {
134*0Sstevel@tonic-gate fstack_t d = (int)get_int(env);
135*0Sstevel@tonic-gate PUSH(DS, d);
136*0Sstevel@tonic-gate literal(env);
137*0Sstevel@tonic-gate }
138*0Sstevel@tonic-gate
139*0Sstevel@tonic-gate void (*bbranch_ptrs[3])(fcode_env_t *env) = {
140*0Sstevel@tonic-gate do_bbranch,
141*0Sstevel@tonic-gate do_bqbranch,
142*0Sstevel@tonic-gate do_bofbranch
143*0Sstevel@tonic-gate };
144*0Sstevel@tonic-gate
145*0Sstevel@tonic-gate void
branch_common(fcode_env_t * env,short direction,fstack_t which,int doswap)146*0Sstevel@tonic-gate branch_common(fcode_env_t *env, short direction, fstack_t which, int doswap)
147*0Sstevel@tonic-gate {
148*0Sstevel@tonic-gate fstack_t *sp;
149*0Sstevel@tonic-gate token_t *branch_loc;
150*0Sstevel@tonic-gate
151*0Sstevel@tonic-gate ASSERT((which < 3) && (which >= 0));
152*0Sstevel@tonic-gate which = (fstack_t)&bbranch_ptrs[which];
153*0Sstevel@tonic-gate set_temporary_compile(env);
154*0Sstevel@tonic-gate COMPILE_TOKEN(which);
155*0Sstevel@tonic-gate if (direction >= 0) {
156*0Sstevel@tonic-gate bmark(env);
157*0Sstevel@tonic-gate if (doswap)
158*0Sstevel@tonic-gate swap(env);
159*0Sstevel@tonic-gate PUSH(DS, 0);
160*0Sstevel@tonic-gate compile_comma(env);
161*0Sstevel@tonic-gate } else {
162*0Sstevel@tonic-gate
163*0Sstevel@tonic-gate /*
164*0Sstevel@tonic-gate * We look down the stack for a branch location
165*0Sstevel@tonic-gate * that isn't pointing to zero (i.e. a forward branch label).
166*0Sstevel@tonic-gate * We move the first one we find to the top of the stack,
167*0Sstevel@tonic-gate * which is what gets compiled in with 'compile_comma'.
168*0Sstevel@tonic-gate * Not finding a valid branch label is bad.
169*0Sstevel@tonic-gate */
170*0Sstevel@tonic-gate for (sp = env->ds; sp >= env->ds0; sp--) {
171*0Sstevel@tonic-gate branch_loc = (token_t *)*sp;
172*0Sstevel@tonic-gate if (branch_loc && *branch_loc) {
173*0Sstevel@tonic-gate break;
174*0Sstevel@tonic-gate }
175*0Sstevel@tonic-gate }
176*0Sstevel@tonic-gate if (sp < env->ds0)
177*0Sstevel@tonic-gate log_message(MSG_ERROR, "branch_common: back: "
178*0Sstevel@tonic-gate "no branch loc on stack\n");
179*0Sstevel@tonic-gate else {
180*0Sstevel@tonic-gate /* Move branch_loc to top of data stack */
181*0Sstevel@tonic-gate for (; sp < env->ds; sp++)
182*0Sstevel@tonic-gate *sp = sp[1];
183*0Sstevel@tonic-gate *sp = (fstack_t)branch_loc;
184*0Sstevel@tonic-gate }
185*0Sstevel@tonic-gate env->level--;
186*0Sstevel@tonic-gate compile_comma(env);
187*0Sstevel@tonic-gate temporary_execute(env);
188*0Sstevel@tonic-gate }
189*0Sstevel@tonic-gate }
190*0Sstevel@tonic-gate
191*0Sstevel@tonic-gate void
bbranch(fcode_env_t * env)192*0Sstevel@tonic-gate bbranch(fcode_env_t *env)
193*0Sstevel@tonic-gate {
194*0Sstevel@tonic-gate short offset = (short)get_short(env);
195*0Sstevel@tonic-gate
196*0Sstevel@tonic-gate branch_common(env, offset, 0, 1);
197*0Sstevel@tonic-gate }
198*0Sstevel@tonic-gate
199*0Sstevel@tonic-gate void
bqbranch(fcode_env_t * env)200*0Sstevel@tonic-gate bqbranch(fcode_env_t *env)
201*0Sstevel@tonic-gate {
202*0Sstevel@tonic-gate short offset = (short)get_short(env);
203*0Sstevel@tonic-gate
204*0Sstevel@tonic-gate branch_common(env, offset, 1, 0);
205*0Sstevel@tonic-gate }
206*0Sstevel@tonic-gate
207*0Sstevel@tonic-gate void
do_quote(fcode_env_t * env)208*0Sstevel@tonic-gate do_quote(fcode_env_t *env)
209*0Sstevel@tonic-gate {
210*0Sstevel@tonic-gate int len;
211*0Sstevel@tonic-gate uchar_t *strptr;
212*0Sstevel@tonic-gate
213*0Sstevel@tonic-gate strptr = (uchar_t *)IP;
214*0Sstevel@tonic-gate len = *strptr;
215*0Sstevel@tonic-gate PUSH(DS, (fstack_t)strptr+1);
216*0Sstevel@tonic-gate PUSH(DS, len);
217*0Sstevel@tonic-gate strptr += TOKEN_ROUNDUP(len+2);
218*0Sstevel@tonic-gate IP = (token_t *)strptr;
219*0Sstevel@tonic-gate }
220*0Sstevel@tonic-gate
221*0Sstevel@tonic-gate void
bquote(fcode_env_t * env)222*0Sstevel@tonic-gate bquote(fcode_env_t *env)
223*0Sstevel@tonic-gate {
224*0Sstevel@tonic-gate char stringbuff[256];
225*0Sstevel@tonic-gate int len, count;
226*0Sstevel@tonic-gate char *strptr;
227*0Sstevel@tonic-gate
228*0Sstevel@tonic-gate count = len = next_bytecode(env);
229*0Sstevel@tonic-gate if (env->state) {
230*0Sstevel@tonic-gate COMPILE_TOKEN("e_ptr);
231*0Sstevel@tonic-gate strptr = (char *)HERE;
232*0Sstevel@tonic-gate *strptr++ = len;
233*0Sstevel@tonic-gate while (count--)
234*0Sstevel@tonic-gate *strptr++ = next_bytecode(env);
235*0Sstevel@tonic-gate *strptr++ = 0;
236*0Sstevel@tonic-gate set_here(env, (uchar_t *)strptr, "bquote");
237*0Sstevel@tonic-gate token_roundup(env, "bquote");
238*0Sstevel@tonic-gate } else {
239*0Sstevel@tonic-gate strptr = stringbuff;
240*0Sstevel@tonic-gate while (count--)
241*0Sstevel@tonic-gate *strptr++ = next_bytecode(env);
242*0Sstevel@tonic-gate *strptr = 0;
243*0Sstevel@tonic-gate push_string(env, stringbuff, len);
244*0Sstevel@tonic-gate }
245*0Sstevel@tonic-gate }
246*0Sstevel@tonic-gate
247*0Sstevel@tonic-gate char *
get_name(token_t * linkp)248*0Sstevel@tonic-gate get_name(token_t *linkp)
249*0Sstevel@tonic-gate {
250*0Sstevel@tonic-gate char *name, *p;
251*0Sstevel@tonic-gate flag_t *fptr = LINK_TO_FLAGS(linkp);
252*0Sstevel@tonic-gate int len;
253*0Sstevel@tonic-gate char *cptr;
254*0Sstevel@tonic-gate
255*0Sstevel@tonic-gate if (*fptr & FLAG_NONAME)
256*0Sstevel@tonic-gate return (NULL);
257*0Sstevel@tonic-gate
258*0Sstevel@tonic-gate cptr = (char *)fptr;
259*0Sstevel@tonic-gate len = cptr[-1];
260*0Sstevel@tonic-gate if (len <= 0 || len > 64 || cptr[-2] != '\0')
261*0Sstevel@tonic-gate return (NULL);
262*0Sstevel@tonic-gate
263*0Sstevel@tonic-gate name = cptr - (len+2);
264*0Sstevel@tonic-gate
265*0Sstevel@tonic-gate for (p = name; *p != '\0'; p++)
266*0Sstevel@tonic-gate if (!isprint(*p))
267*0Sstevel@tonic-gate return (NULL);
268*0Sstevel@tonic-gate
269*0Sstevel@tonic-gate if ((p - name) != len)
270*0Sstevel@tonic-gate return (NULL);
271*0Sstevel@tonic-gate
272*0Sstevel@tonic-gate return (name);
273*0Sstevel@tonic-gate }
274*0Sstevel@tonic-gate
275*0Sstevel@tonic-gate void
header(fcode_env_t * env,char * name,int len,flag_t flag)276*0Sstevel@tonic-gate header(fcode_env_t *env, char *name, int len, flag_t flag)
277*0Sstevel@tonic-gate {
278*0Sstevel@tonic-gate char *strptr;
279*0Sstevel@tonic-gate flag_t *fptr;
280*0Sstevel@tonic-gate acf_t dptr;
281*0Sstevel@tonic-gate extern void add_debug_acf(fcode_env_t *, acf_t);
282*0Sstevel@tonic-gate
283*0Sstevel@tonic-gate /* Now form the entry in the dictionary */
284*0Sstevel@tonic-gate token_roundup(env, "header");
285*0Sstevel@tonic-gate dptr = (acf_t)HERE;
286*0Sstevel@tonic-gate if (len) {
287*0Sstevel@tonic-gate int bytes = len+2+sizeof (flag_t);
288*0Sstevel@tonic-gate dptr = (acf_t)(TOKEN_ROUNDUP(HERE+bytes));
289*0Sstevel@tonic-gate fptr = LINK_TO_FLAGS(dptr);
290*0Sstevel@tonic-gate strptr = (char *)fptr - 1;
291*0Sstevel@tonic-gate *strptr-- = len;
292*0Sstevel@tonic-gate *strptr-- = 0;
293*0Sstevel@tonic-gate while (len)
294*0Sstevel@tonic-gate *strptr-- = name[--len];
295*0Sstevel@tonic-gate } else {
296*0Sstevel@tonic-gate dptr++;
297*0Sstevel@tonic-gate fptr = LINK_TO_FLAGS(dptr);
298*0Sstevel@tonic-gate flag |= FLAG_NONAME;
299*0Sstevel@tonic-gate }
300*0Sstevel@tonic-gate *fptr = flag;
301*0Sstevel@tonic-gate *dptr = *((acf_t)env->current);
302*0Sstevel@tonic-gate env->lastlink = dptr++;
303*0Sstevel@tonic-gate set_here(env, (uchar_t *)dptr, "header");
304*0Sstevel@tonic-gate
305*0Sstevel@tonic-gate if (name_is_debugged(env, name)) {
306*0Sstevel@tonic-gate log_message(MSG_INFO, "Turning debug on for %s\n", name);
307*0Sstevel@tonic-gate add_debug_acf(env, LINK_TO_ACF(env->lastlink));
308*0Sstevel@tonic-gate }
309*0Sstevel@tonic-gate debug_msg(DEBUG_HEADER, "Define: '%s' @ %p\n", name, HERE);
310*0Sstevel@tonic-gate }
311*0Sstevel@tonic-gate
312*0Sstevel@tonic-gate void
token_common(fcode_env_t * env,int headered,int visible)313*0Sstevel@tonic-gate token_common(fcode_env_t *env, int headered, int visible)
314*0Sstevel@tonic-gate {
315*0Sstevel@tonic-gate char namebuff[32];
316*0Sstevel@tonic-gate int len, count, token;
317*0Sstevel@tonic-gate char *strptr, c;
318*0Sstevel@tonic-gate
319*0Sstevel@tonic-gate strptr = namebuff;
320*0Sstevel@tonic-gate if (headered) {
321*0Sstevel@tonic-gate len = next_bytecode(env);
322*0Sstevel@tonic-gate for (count = 0; count < len; count++) {
323*0Sstevel@tonic-gate c = next_bytecode(env);
324*0Sstevel@tonic-gate if (count < sizeof (namebuff))
325*0Sstevel@tonic-gate *strptr++ = c;
326*0Sstevel@tonic-gate }
327*0Sstevel@tonic-gate }
328*0Sstevel@tonic-gate
329*0Sstevel@tonic-gate if (!visible)
330*0Sstevel@tonic-gate len = 0;
331*0Sstevel@tonic-gate *strptr = 0;
332*0Sstevel@tonic-gate token = get_short(env);
333*0Sstevel@tonic-gate env->last_token = token;
334*0Sstevel@tonic-gate
335*0Sstevel@tonic-gate debug_msg(DEBUG_NEW_TOKEN, "Define %s token: '%s' (%x)\n",
336*0Sstevel@tonic-gate (visible ? "named" : "headerless"), namebuff, token);
337*0Sstevel@tonic-gate
338*0Sstevel@tonic-gate header(env, namebuff, len, 0);
339*0Sstevel@tonic-gate env->table[token].flags = 0;
340*0Sstevel@tonic-gate if (len) {
341*0Sstevel@tonic-gate env->table[token].name = MALLOC(len+1);
342*0Sstevel@tonic-gate strncpy(env->table[token].name, namebuff, len);
343*0Sstevel@tonic-gate } else {
344*0Sstevel@tonic-gate env->table[token].name = NULL;
345*0Sstevel@tonic-gate }
346*0Sstevel@tonic-gate env->last_token = token;
347*0Sstevel@tonic-gate }
348*0Sstevel@tonic-gate
349*0Sstevel@tonic-gate void
named_token(fcode_env_t * env)350*0Sstevel@tonic-gate named_token(fcode_env_t *env)
351*0Sstevel@tonic-gate {
352*0Sstevel@tonic-gate token_common(env, 1, env->fcode_debug);
353*0Sstevel@tonic-gate }
354*0Sstevel@tonic-gate
355*0Sstevel@tonic-gate void
external_token(fcode_env_t * env)356*0Sstevel@tonic-gate external_token(fcode_env_t *env)
357*0Sstevel@tonic-gate {
358*0Sstevel@tonic-gate token_common(env, 1, 1);
359*0Sstevel@tonic-gate }
360*0Sstevel@tonic-gate
361*0Sstevel@tonic-gate void
new_token(fcode_env_t * env)362*0Sstevel@tonic-gate new_token(fcode_env_t *env)
363*0Sstevel@tonic-gate {
364*0Sstevel@tonic-gate token_common(env, 0, 0);
365*0Sstevel@tonic-gate }
366*0Sstevel@tonic-gate
367*0Sstevel@tonic-gate void
offset16(fcode_env_t * env)368*0Sstevel@tonic-gate offset16(fcode_env_t *env)
369*0Sstevel@tonic-gate {
370*0Sstevel@tonic-gate env->offset_incr = 2;
371*0Sstevel@tonic-gate }
372*0Sstevel@tonic-gate
373*0Sstevel@tonic-gate void
minus_one(fcode_env_t * env)374*0Sstevel@tonic-gate minus_one(fcode_env_t *env)
375*0Sstevel@tonic-gate {
376*0Sstevel@tonic-gate PUSH(DS, -1);
377*0Sstevel@tonic-gate }
378*0Sstevel@tonic-gate
379*0Sstevel@tonic-gate void
zero(fcode_env_t * env)380*0Sstevel@tonic-gate zero(fcode_env_t *env)
381*0Sstevel@tonic-gate {
382*0Sstevel@tonic-gate PUSH(DS, 0);
383*0Sstevel@tonic-gate }
384*0Sstevel@tonic-gate
385*0Sstevel@tonic-gate void
one(fcode_env_t * env)386*0Sstevel@tonic-gate one(fcode_env_t *env)
387*0Sstevel@tonic-gate {
388*0Sstevel@tonic-gate PUSH(DS, 1);
389*0Sstevel@tonic-gate }
390*0Sstevel@tonic-gate
391*0Sstevel@tonic-gate void
two(fcode_env_t * env)392*0Sstevel@tonic-gate two(fcode_env_t *env)
393*0Sstevel@tonic-gate {
394*0Sstevel@tonic-gate PUSH(DS, 2);
395*0Sstevel@tonic-gate }
396*0Sstevel@tonic-gate
397*0Sstevel@tonic-gate void
three(fcode_env_t * env)398*0Sstevel@tonic-gate three(fcode_env_t *env)
399*0Sstevel@tonic-gate {
400*0Sstevel@tonic-gate PUSH(DS, 3);
401*0Sstevel@tonic-gate }
402*0Sstevel@tonic-gate
403*0Sstevel@tonic-gate void
version1(fcode_env_t * env)404*0Sstevel@tonic-gate version1(fcode_env_t *env)
405*0Sstevel@tonic-gate {
406*0Sstevel@tonic-gate env->fcode_incr = 1;
407*0Sstevel@tonic-gate }
408*0Sstevel@tonic-gate
409*0Sstevel@tonic-gate static void
start0(fcode_env_t * env)410*0Sstevel@tonic-gate start0(fcode_env_t *env)
411*0Sstevel@tonic-gate {
412*0Sstevel@tonic-gate env->fcode_incr = 1;
413*0Sstevel@tonic-gate }
414*0Sstevel@tonic-gate
415*0Sstevel@tonic-gate static void
start1(fcode_env_t * env)416*0Sstevel@tonic-gate start1(fcode_env_t *env)
417*0Sstevel@tonic-gate {
418*0Sstevel@tonic-gate env->fcode_incr = 1;
419*0Sstevel@tonic-gate }
420*0Sstevel@tonic-gate
421*0Sstevel@tonic-gate void
start2(fcode_env_t * env)422*0Sstevel@tonic-gate start2(fcode_env_t *env)
423*0Sstevel@tonic-gate {
424*0Sstevel@tonic-gate env->fcode_incr = 2;
425*0Sstevel@tonic-gate }
426*0Sstevel@tonic-gate
427*0Sstevel@tonic-gate static void
start4(fcode_env_t * env)428*0Sstevel@tonic-gate start4(fcode_env_t *env)
429*0Sstevel@tonic-gate {
430*0Sstevel@tonic-gate env->fcode_incr = 4;
431*0Sstevel@tonic-gate }
432*0Sstevel@tonic-gate
433*0Sstevel@tonic-gate int
check_fcode_header(char * fname,uchar_t * header,int len)434*0Sstevel@tonic-gate check_fcode_header(char *fname, uchar_t *header, int len)
435*0Sstevel@tonic-gate {
436*0Sstevel@tonic-gate uint32_t length;
437*0Sstevel@tonic-gate static char func_name[] = "check_fcode_header";
438*0Sstevel@tonic-gate
439*0Sstevel@tonic-gate if (len <= 8) {
440*0Sstevel@tonic-gate log_message(MSG_ERROR, "%s: '%s' fcode size (%d) <= 8\n",
441*0Sstevel@tonic-gate func_name, fname, len);
442*0Sstevel@tonic-gate return (0);
443*0Sstevel@tonic-gate }
444*0Sstevel@tonic-gate if (header[0] != 0xf1 && header[0] != 0xfd) {
445*0Sstevel@tonic-gate log_message(MSG_ERROR, "%s: '%s' header[0] is 0x%02x not"
446*0Sstevel@tonic-gate " 0xf1/0xfd\n", func_name, fname, header[0]);
447*0Sstevel@tonic-gate return (0);
448*0Sstevel@tonic-gate }
449*0Sstevel@tonic-gate length = (header[4] << 24) | (header[5] << 16) | (header[6] << 8) |
450*0Sstevel@tonic-gate header[7];
451*0Sstevel@tonic-gate if (length > len) {
452*0Sstevel@tonic-gate log_message(MSG_ERROR, "%s: '%s' length (%d) >"
453*0Sstevel@tonic-gate " fcode size (%d)\n", func_name, fname, length, len);
454*0Sstevel@tonic-gate return (0);
455*0Sstevel@tonic-gate }
456*0Sstevel@tonic-gate if (length < len) {
457*0Sstevel@tonic-gate log_message(MSG_WARN, "%s: '%s' length (%d) <"
458*0Sstevel@tonic-gate " fcode size (%d)\n", func_name, fname, length, len);
459*0Sstevel@tonic-gate }
460*0Sstevel@tonic-gate return (1);
461*0Sstevel@tonic-gate }
462*0Sstevel@tonic-gate
463*0Sstevel@tonic-gate void
byte_load(fcode_env_t * env)464*0Sstevel@tonic-gate byte_load(fcode_env_t *env)
465*0Sstevel@tonic-gate {
466*0Sstevel@tonic-gate uchar_t *fcode_buffer;
467*0Sstevel@tonic-gate uchar_t *fcode_ptr;
468*0Sstevel@tonic-gate int fcode_incr;
469*0Sstevel@tonic-gate int offset_incr;
470*0Sstevel@tonic-gate int fcode_xt;
471*0Sstevel@tonic-gate int interpretting;
472*0Sstevel@tonic-gate int depth;
473*0Sstevel@tonic-gate int length;
474*0Sstevel@tonic-gate int past_eob = 0;
475*0Sstevel@tonic-gate int db;
476*0Sstevel@tonic-gate
477*0Sstevel@tonic-gate /* save any existing interpret state */
478*0Sstevel@tonic-gate fcode_buffer = env->fcode_buffer;
479*0Sstevel@tonic-gate fcode_ptr = env->fcode_ptr;
480*0Sstevel@tonic-gate fcode_incr = env->fcode_incr;
481*0Sstevel@tonic-gate offset_incr = env->offset_incr;
482*0Sstevel@tonic-gate interpretting = env->interpretting;
483*0Sstevel@tonic-gate depth = DEPTH-2;
484*0Sstevel@tonic-gate
485*0Sstevel@tonic-gate /* Now init them */
486*0Sstevel@tonic-gate CHECK_DEPTH(env, 2, "byte-load");
487*0Sstevel@tonic-gate fcode_xt = POP(DS);
488*0Sstevel@tonic-gate env->fcode_ptr = env->fcode_buffer = (uchar_t *)POP(DS);
489*0Sstevel@tonic-gate if (fcode_xt != 1) {
490*0Sstevel@tonic-gate log_message(MSG_WARN, "byte-load: ignoring xt\n");
491*0Sstevel@tonic-gate }
492*0Sstevel@tonic-gate
493*0Sstevel@tonic-gate length = (env->fcode_buffer[4] << 24) | (env->fcode_buffer[5] << 16) |
494*0Sstevel@tonic-gate (env->fcode_buffer[6] << 8) | env->fcode_buffer[7];
495*0Sstevel@tonic-gate if (!check_fcode_header("byte-load", env->fcode_ptr, length))
496*0Sstevel@tonic-gate log_message(MSG_WARN, "byte-load: header NOT OK\n");
497*0Sstevel@tonic-gate
498*0Sstevel@tonic-gate env->fcode_incr = 1;
499*0Sstevel@tonic-gate env->offset_incr = 1;
500*0Sstevel@tonic-gate env->interpretting = 1;
501*0Sstevel@tonic-gate env->level = 0;
502*0Sstevel@tonic-gate
503*0Sstevel@tonic-gate db = get_interpreter_debug_level() &
504*0Sstevel@tonic-gate (DEBUG_BYTELOAD_DS|DEBUG_BYTELOAD_RS|DEBUG_BYTELOAD_TOKENS);
505*0Sstevel@tonic-gate debug_msg(db, "byte_load: %p, %d\n", env->fcode_buffer, fcode_xt);
506*0Sstevel@tonic-gate debug_msg(db, " header: %x, %x\n",
507*0Sstevel@tonic-gate env->fcode_buffer[0], env->fcode_buffer[1]);
508*0Sstevel@tonic-gate debug_msg(db, " crc: %x\n",
509*0Sstevel@tonic-gate (env->fcode_buffer[2]<<8)|(env->fcode_buffer[3]));
510*0Sstevel@tonic-gate debug_msg(db, " length: %x\n", length);
511*0Sstevel@tonic-gate env->fcode_ptr += 8;
512*0Sstevel@tonic-gate
513*0Sstevel@tonic-gate debug_msg(db, "Interpretting: %d\n", env->interpretting);
514*0Sstevel@tonic-gate
515*0Sstevel@tonic-gate while (env->interpretting) {
516*0Sstevel@tonic-gate int token;
517*0Sstevel@tonic-gate fcode_token *entry;
518*0Sstevel@tonic-gate acf_t apf;
519*0Sstevel@tonic-gate
520*0Sstevel@tonic-gate if (!past_eob && env->fcode_ptr >= env->fcode_buffer + length) {
521*0Sstevel@tonic-gate log_message(MSG_WARN, "byte-load: past EOB\n");
522*0Sstevel@tonic-gate past_eob = 1;
523*0Sstevel@tonic-gate }
524*0Sstevel@tonic-gate
525*0Sstevel@tonic-gate env->last_fcode_ptr = env->fcode_ptr;
526*0Sstevel@tonic-gate token = get_next_token(env);
527*0Sstevel@tonic-gate
528*0Sstevel@tonic-gate entry = &env->table[token];
529*0Sstevel@tonic-gate apf = entry->apf;
530*0Sstevel@tonic-gate
531*0Sstevel@tonic-gate DEBUGF(BYTELOAD_DS, output_data_stack(env, MSG_FC_DEBUG));
532*0Sstevel@tonic-gate DEBUGF(BYTELOAD_RS, output_return_stack(env, 1, MSG_FC_DEBUG));
533*0Sstevel@tonic-gate DEBUGF(BYTELOAD_TOKENS, log_message(MSG_FC_DEBUG,
534*0Sstevel@tonic-gate "%s: %04x %03x %s (%x)",
535*0Sstevel@tonic-gate ((env->state && (entry->flags & IMMEDIATE) == 0)) ?
536*0Sstevel@tonic-gate "Compile" : "Execute",
537*0Sstevel@tonic-gate env->last_fcode_ptr - env->fcode_buffer, token,
538*0Sstevel@tonic-gate entry->name ? entry->name : "???", entry->flags));
539*0Sstevel@tonic-gate if (db)
540*0Sstevel@tonic-gate log_message(MSG_FC_DEBUG, "\n");
541*0Sstevel@tonic-gate if (apf) {
542*0Sstevel@tonic-gate DEBUGF(TOKEN_USAGE, entry->usage++);
543*0Sstevel@tonic-gate PUSH(DS, (fstack_t)apf);
544*0Sstevel@tonic-gate if ((env->state) &&
545*0Sstevel@tonic-gate ((entry->flags & IMMEDIATE) == 0)) {
546*0Sstevel@tonic-gate /* Compile in references */
547*0Sstevel@tonic-gate compile_comma(env);
548*0Sstevel@tonic-gate } else {
549*0Sstevel@tonic-gate execute(env);
550*0Sstevel@tonic-gate }
551*0Sstevel@tonic-gate }
552*0Sstevel@tonic-gate }
553*0Sstevel@tonic-gate if (DEPTH != depth) {
554*0Sstevel@tonic-gate log_message(MSG_ERROR, "FCODE has net stack change of %d\n",
555*0Sstevel@tonic-gate DEPTH-depth);
556*0Sstevel@tonic-gate }
557*0Sstevel@tonic-gate /* restore old state */
558*0Sstevel@tonic-gate env->fcode_ptr = fcode_ptr;
559*0Sstevel@tonic-gate env->fcode_buffer = fcode_buffer;
560*0Sstevel@tonic-gate env->fcode_incr = fcode_incr;
561*0Sstevel@tonic-gate env->offset_incr = offset_incr;
562*0Sstevel@tonic-gate env->interpretting = interpretting;
563*0Sstevel@tonic-gate }
564*0Sstevel@tonic-gate
565*0Sstevel@tonic-gate void
btick(fcode_env_t * env)566*0Sstevel@tonic-gate btick(fcode_env_t *env)
567*0Sstevel@tonic-gate {
568*0Sstevel@tonic-gate int token = get_next_token(env);
569*0Sstevel@tonic-gate
570*0Sstevel@tonic-gate PUSH(DS, (fstack_t)env->table[token].apf);
571*0Sstevel@tonic-gate tick_literal(env);
572*0Sstevel@tonic-gate }
573*0Sstevel@tonic-gate
574*0Sstevel@tonic-gate static void
show_fcode_def(fcode_env_t * env,char * type)575*0Sstevel@tonic-gate show_fcode_def(fcode_env_t *env, char *type)
576*0Sstevel@tonic-gate {
577*0Sstevel@tonic-gate int i = env->last_token;
578*0Sstevel@tonic-gate
579*0Sstevel@tonic-gate if (get_interpreter_debug_level() & DEBUG_DUMP_TOKENS) {
580*0Sstevel@tonic-gate if (env->table[i].name)
581*0Sstevel@tonic-gate log_message(MSG_INFO, "%s: %s %03x %p\n", type,
582*0Sstevel@tonic-gate env->table[i].name, i, env->table[i].apf);
583*0Sstevel@tonic-gate else
584*0Sstevel@tonic-gate log_message(MSG_INFO, "%s: <noname> %03x %p\n", type, i,
585*0Sstevel@tonic-gate env->table[i].apf);
586*0Sstevel@tonic-gate }
587*0Sstevel@tonic-gate }
588*0Sstevel@tonic-gate
589*0Sstevel@tonic-gate void
bcolon(fcode_env_t * env)590*0Sstevel@tonic-gate bcolon(fcode_env_t *env)
591*0Sstevel@tonic-gate {
592*0Sstevel@tonic-gate if (env->state == 0) {
593*0Sstevel@tonic-gate env->table[env->last_token].apf = (acf_t)HERE;
594*0Sstevel@tonic-gate env->table[env->last_token].flags = 0;
595*0Sstevel@tonic-gate show_fcode_def(env, "bcolon");
596*0Sstevel@tonic-gate }
597*0Sstevel@tonic-gate env->state |= 1;
598*0Sstevel@tonic-gate COMPILE_TOKEN(&do_colon);
599*0Sstevel@tonic-gate }
600*0Sstevel@tonic-gate
601*0Sstevel@tonic-gate void
bcreate(fcode_env_t * env)602*0Sstevel@tonic-gate bcreate(fcode_env_t *env)
603*0Sstevel@tonic-gate {
604*0Sstevel@tonic-gate env->table[env->last_token].apf = (acf_t)HERE;
605*0Sstevel@tonic-gate show_fcode_def(env, "bcreate");
606*0Sstevel@tonic-gate COMPILE_TOKEN(&do_create);
607*0Sstevel@tonic-gate expose_acf(env, "<bcreate>");
608*0Sstevel@tonic-gate }
609*0Sstevel@tonic-gate
610*0Sstevel@tonic-gate void
get_token_name(fcode_env_t * env,int token,char ** name,int * len)611*0Sstevel@tonic-gate get_token_name(fcode_env_t *env, int token, char **name, int *len)
612*0Sstevel@tonic-gate {
613*0Sstevel@tonic-gate *name = env->table[token].name;
614*0Sstevel@tonic-gate if (*name) {
615*0Sstevel@tonic-gate *len = strlen(*name);
616*0Sstevel@tonic-gate } else
617*0Sstevel@tonic-gate *len = 0;
618*0Sstevel@tonic-gate }
619*0Sstevel@tonic-gate
620*0Sstevel@tonic-gate void
bvalue(fcode_env_t * env)621*0Sstevel@tonic-gate bvalue(fcode_env_t *env)
622*0Sstevel@tonic-gate {
623*0Sstevel@tonic-gate env->table[env->last_token].apf = (acf_t)HERE;
624*0Sstevel@tonic-gate show_fcode_def(env, "bvalue");
625*0Sstevel@tonic-gate make_common_access(env, 0, 0, 1,
626*0Sstevel@tonic-gate env->instance_mode, &noop, &noop, &set_value_actions);
627*0Sstevel@tonic-gate }
628*0Sstevel@tonic-gate
629*0Sstevel@tonic-gate void
bvariable(fcode_env_t * env)630*0Sstevel@tonic-gate bvariable(fcode_env_t *env)
631*0Sstevel@tonic-gate {
632*0Sstevel@tonic-gate env->table[env->last_token].apf = (acf_t)HERE;
633*0Sstevel@tonic-gate show_fcode_def(env, "bvariable");
634*0Sstevel@tonic-gate PUSH(DS, 0);
635*0Sstevel@tonic-gate make_common_access(env, 0, 0, 1,
636*0Sstevel@tonic-gate env->instance_mode, &instance_variable, &do_create, NULL);
637*0Sstevel@tonic-gate }
638*0Sstevel@tonic-gate
639*0Sstevel@tonic-gate void
bconstant(fcode_env_t * env)640*0Sstevel@tonic-gate bconstant(fcode_env_t *env)
641*0Sstevel@tonic-gate {
642*0Sstevel@tonic-gate env->table[env->last_token].apf = (acf_t)HERE;
643*0Sstevel@tonic-gate show_fcode_def(env, "bconstant");
644*0Sstevel@tonic-gate make_common_access(env, 0, 0, 1,
645*0Sstevel@tonic-gate env->instance_mode, &do_constant, &do_constant, NULL);
646*0Sstevel@tonic-gate }
647*0Sstevel@tonic-gate
648*0Sstevel@tonic-gate void
bdefer(fcode_env_t * env)649*0Sstevel@tonic-gate bdefer(fcode_env_t *env)
650*0Sstevel@tonic-gate {
651*0Sstevel@tonic-gate env->table[env->last_token].apf = (acf_t)HERE;
652*0Sstevel@tonic-gate show_fcode_def(env, "bdefer");
653*0Sstevel@tonic-gate
654*0Sstevel@tonic-gate PUSH(DS, (fstack_t)&crash_ptr);
655*0Sstevel@tonic-gate make_common_access(env, 0, 0, 1, env->instance_mode,
656*0Sstevel@tonic-gate &noop, &noop, &set_defer_actions);
657*0Sstevel@tonic-gate }
658*0Sstevel@tonic-gate
659*0Sstevel@tonic-gate void
bbuffer_colon(fcode_env_t * env)660*0Sstevel@tonic-gate bbuffer_colon(fcode_env_t *env)
661*0Sstevel@tonic-gate {
662*0Sstevel@tonic-gate env->table[env->last_token].apf = (acf_t)HERE;
663*0Sstevel@tonic-gate show_fcode_def(env, "buffer:");
664*0Sstevel@tonic-gate PUSH(DS, 0);
665*0Sstevel@tonic-gate make_common_access(env, 0, 0, 2, env->instance_mode,
666*0Sstevel@tonic-gate &noop, &noop, &set_buffer_actions);
667*0Sstevel@tonic-gate }
668*0Sstevel@tonic-gate
669*0Sstevel@tonic-gate void
do_field(fcode_env_t * env)670*0Sstevel@tonic-gate do_field(fcode_env_t *env)
671*0Sstevel@tonic-gate {
672*0Sstevel@tonic-gate fstack_t *d;
673*0Sstevel@tonic-gate
674*0Sstevel@tonic-gate d = (fstack_t *)WA;
675*0Sstevel@tonic-gate TOS += *d;
676*0Sstevel@tonic-gate }
677*0Sstevel@tonic-gate
678*0Sstevel@tonic-gate void
bfield(fcode_env_t * env)679*0Sstevel@tonic-gate bfield(fcode_env_t *env)
680*0Sstevel@tonic-gate {
681*0Sstevel@tonic-gate env->table[env->last_token].apf = (acf_t)HERE;
682*0Sstevel@tonic-gate show_fcode_def(env, "bfield");
683*0Sstevel@tonic-gate COMPILE_TOKEN(&do_field);
684*0Sstevel@tonic-gate over(env);
685*0Sstevel@tonic-gate compile_comma(env);
686*0Sstevel@tonic-gate add(env);
687*0Sstevel@tonic-gate expose_acf(env, "<bfield>");
688*0Sstevel@tonic-gate }
689*0Sstevel@tonic-gate
690*0Sstevel@tonic-gate void
bto(fcode_env_t * env)691*0Sstevel@tonic-gate bto(fcode_env_t *env)
692*0Sstevel@tonic-gate {
693*0Sstevel@tonic-gate btick(env);
694*0Sstevel@tonic-gate
695*0Sstevel@tonic-gate if (env->state) {
696*0Sstevel@tonic-gate COMPILE_TOKEN(&to_ptr);
697*0Sstevel@tonic-gate } else {
698*0Sstevel@tonic-gate do_set_action(env);
699*0Sstevel@tonic-gate }
700*0Sstevel@tonic-gate }
701*0Sstevel@tonic-gate
702*0Sstevel@tonic-gate void
get_token(fcode_env_t * env)703*0Sstevel@tonic-gate get_token(fcode_env_t *env)
704*0Sstevel@tonic-gate {
705*0Sstevel@tonic-gate fstack_t tok;
706*0Sstevel@tonic-gate fstack_t immediate = 0;
707*0Sstevel@tonic-gate
708*0Sstevel@tonic-gate CHECK_DEPTH(env, 1, "get-token");
709*0Sstevel@tonic-gate tok = POP(DS);
710*0Sstevel@tonic-gate tok &= MAX_FCODE;
711*0Sstevel@tonic-gate PUSH(DS, (fstack_t)env->table[tok].apf);
712*0Sstevel@tonic-gate if (env->table[tok].flags & IMMEDIATE) immediate = 1;
713*0Sstevel@tonic-gate PUSH(DS, immediate);
714*0Sstevel@tonic-gate }
715*0Sstevel@tonic-gate
716*0Sstevel@tonic-gate void
set_token(fcode_env_t * env)717*0Sstevel@tonic-gate set_token(fcode_env_t *env)
718*0Sstevel@tonic-gate {
719*0Sstevel@tonic-gate fstack_t tok;
720*0Sstevel@tonic-gate fstack_t immediate;
721*0Sstevel@tonic-gate acf_t acf;
722*0Sstevel@tonic-gate
723*0Sstevel@tonic-gate CHECK_DEPTH(env, 3, "set-token");
724*0Sstevel@tonic-gate tok = POP(DS);
725*0Sstevel@tonic-gate tok &= MAX_FCODE;
726*0Sstevel@tonic-gate immediate = POP(DS);
727*0Sstevel@tonic-gate acf = (acf_t)POP(DS);
728*0Sstevel@tonic-gate if (immediate)
729*0Sstevel@tonic-gate env->table[tok].flags |= IMMEDIATE;
730*0Sstevel@tonic-gate else
731*0Sstevel@tonic-gate env->table[tok].flags &= ~IMMEDIATE;
732*0Sstevel@tonic-gate env->table[tok].apf = acf;
733*0Sstevel@tonic-gate immediate = env->last_token;
734*0Sstevel@tonic-gate env->last_token = tok;
735*0Sstevel@tonic-gate show_fcode_def(env, "set_token");
736*0Sstevel@tonic-gate env->last_token = immediate;
737*0Sstevel@tonic-gate }
738*0Sstevel@tonic-gate
739*0Sstevel@tonic-gate void
bof(fcode_env_t * env)740*0Sstevel@tonic-gate bof(fcode_env_t *env)
741*0Sstevel@tonic-gate {
742*0Sstevel@tonic-gate short offset = get_short(env);
743*0Sstevel@tonic-gate branch_common(env, offset, 2, 0);
744*0Sstevel@tonic-gate }
745*0Sstevel@tonic-gate
746*0Sstevel@tonic-gate void
bcase(fcode_env_t * env)747*0Sstevel@tonic-gate bcase(fcode_env_t *env)
748*0Sstevel@tonic-gate {
749*0Sstevel@tonic-gate env->level++;
750*0Sstevel@tonic-gate set_temporary_compile(env);
751*0Sstevel@tonic-gate PUSH(DS, 0);
752*0Sstevel@tonic-gate }
753*0Sstevel@tonic-gate
754*0Sstevel@tonic-gate void
bendcase(fcode_env_t * env)755*0Sstevel@tonic-gate bendcase(fcode_env_t *env)
756*0Sstevel@tonic-gate {
757*0Sstevel@tonic-gate COMPILE_TOKEN(env->table[0x46].apf); /* Hack for now... */
758*0Sstevel@tonic-gate while (TOS) {
759*0Sstevel@tonic-gate bresolve(env);
760*0Sstevel@tonic-gate }
761*0Sstevel@tonic-gate (void) POP(DS);
762*0Sstevel@tonic-gate env->level--;
763*0Sstevel@tonic-gate temporary_execute(env);
764*0Sstevel@tonic-gate }
765*0Sstevel@tonic-gate
766*0Sstevel@tonic-gate void
bendof(fcode_env_t * env)767*0Sstevel@tonic-gate bendof(fcode_env_t *env)
768*0Sstevel@tonic-gate {
769*0Sstevel@tonic-gate short offset = get_short(env);
770*0Sstevel@tonic-gate branch_common(env, offset, 0, 1);
771*0Sstevel@tonic-gate bresolve(env);
772*0Sstevel@tonic-gate }
773*0Sstevel@tonic-gate
774*0Sstevel@tonic-gate void
fcode_revision(fcode_env_t * env)775*0Sstevel@tonic-gate fcode_revision(fcode_env_t *env)
776*0Sstevel@tonic-gate {
777*0Sstevel@tonic-gate /* We are Version 3.0 */
778*0Sstevel@tonic-gate PUSH(DS, 0x30000);
779*0Sstevel@tonic-gate }
780*0Sstevel@tonic-gate
781*0Sstevel@tonic-gate void
alloc_mem(fcode_env_t * env)782*0Sstevel@tonic-gate alloc_mem(fcode_env_t *env)
783*0Sstevel@tonic-gate {
784*0Sstevel@tonic-gate CHECK_DEPTH(env, 1, "alloc-mem");
785*0Sstevel@tonic-gate TOS = (fstack_t)MALLOC((size_t)TOS);
786*0Sstevel@tonic-gate if (!TOS) {
787*0Sstevel@tonic-gate throw_from_fclib(env, 1, "alloc-mem failed");
788*0Sstevel@tonic-gate }
789*0Sstevel@tonic-gate }
790*0Sstevel@tonic-gate
791*0Sstevel@tonic-gate void
free_mem(fcode_env_t * env)792*0Sstevel@tonic-gate free_mem(fcode_env_t *env)
793*0Sstevel@tonic-gate {
794*0Sstevel@tonic-gate void *p;
795*0Sstevel@tonic-gate
796*0Sstevel@tonic-gate CHECK_DEPTH(env, 2, "free-mem");
797*0Sstevel@tonic-gate (void) POP(DS);
798*0Sstevel@tonic-gate p = (void *) POP(DS);
799*0Sstevel@tonic-gate FREE(p);
800*0Sstevel@tonic-gate }
801*0Sstevel@tonic-gate
802*0Sstevel@tonic-gate void
parse_two_int(fcode_env_t * env)803*0Sstevel@tonic-gate parse_two_int(fcode_env_t *env)
804*0Sstevel@tonic-gate {
805*0Sstevel@tonic-gate uint_t lo, hi;
806*0Sstevel@tonic-gate char *str;
807*0Sstevel@tonic-gate int len;
808*0Sstevel@tonic-gate
809*0Sstevel@tonic-gate CHECK_DEPTH(env, 2, "parse-2int");
810*0Sstevel@tonic-gate lo = 0;
811*0Sstevel@tonic-gate hi = 0;
812*0Sstevel@tonic-gate str = pop_a_string(env, &len);
813*0Sstevel@tonic-gate if (len) {
814*0Sstevel@tonic-gate if (sscanf(str, "%x,%x", &hi, &lo) != 2) {
815*0Sstevel@tonic-gate throw_from_fclib(env, 1, "parse_2int");
816*0Sstevel@tonic-gate }
817*0Sstevel@tonic-gate }
818*0Sstevel@tonic-gate PUSH(DS, lo);
819*0Sstevel@tonic-gate PUSH(DS, hi);
820*0Sstevel@tonic-gate }
821*0Sstevel@tonic-gate
822*0Sstevel@tonic-gate void
left_parse_string(fcode_env_t * env)823*0Sstevel@tonic-gate left_parse_string(fcode_env_t *env)
824*0Sstevel@tonic-gate {
825*0Sstevel@tonic-gate char sep, *cptr, *lstr, *rstr;
826*0Sstevel@tonic-gate int len, llen, rlen;
827*0Sstevel@tonic-gate
828*0Sstevel@tonic-gate CHECK_DEPTH(env, 3, "left-parse-string");
829*0Sstevel@tonic-gate sep = (char)POP(DS);
830*0Sstevel@tonic-gate if (TOS == 0) {
831*0Sstevel@tonic-gate two_dup(env);
832*0Sstevel@tonic-gate return;
833*0Sstevel@tonic-gate }
834*0Sstevel@tonic-gate lstr = pop_a_string(env, &llen);
835*0Sstevel@tonic-gate len = 0;
836*0Sstevel@tonic-gate cptr = NULL;
837*0Sstevel@tonic-gate while (len < llen) {
838*0Sstevel@tonic-gate if (lstr[len] == sep) {
839*0Sstevel@tonic-gate cptr = lstr+len;
840*0Sstevel@tonic-gate break;
841*0Sstevel@tonic-gate }
842*0Sstevel@tonic-gate len++;
843*0Sstevel@tonic-gate }
844*0Sstevel@tonic-gate if (cptr != NULL) {
845*0Sstevel@tonic-gate rstr = cptr+1;
846*0Sstevel@tonic-gate rlen = lstr + llen - rstr;
847*0Sstevel@tonic-gate llen = len;
848*0Sstevel@tonic-gate } else {
849*0Sstevel@tonic-gate rlen = 0;
850*0Sstevel@tonic-gate rstr = lstr;
851*0Sstevel@tonic-gate }
852*0Sstevel@tonic-gate PUSH(DS, (fstack_t)rstr);
853*0Sstevel@tonic-gate PUSH(DS, rlen);
854*0Sstevel@tonic-gate PUSH(DS, (fstack_t)lstr);
855*0Sstevel@tonic-gate PUSH(DS, llen);
856*0Sstevel@tonic-gate }
857*0Sstevel@tonic-gate
858*0Sstevel@tonic-gate /*
859*0Sstevel@tonic-gate * (is-user-word) ( name-str name-len xt -- )
860*0Sstevel@tonic-gate */
861*0Sstevel@tonic-gate void
is_user_word(fcode_env_t * env)862*0Sstevel@tonic-gate is_user_word(fcode_env_t *env)
863*0Sstevel@tonic-gate {
864*0Sstevel@tonic-gate fstack_t xt;
865*0Sstevel@tonic-gate char *name;
866*0Sstevel@tonic-gate int len;
867*0Sstevel@tonic-gate
868*0Sstevel@tonic-gate CHECK_DEPTH(env, 3, "(is-user-word)");
869*0Sstevel@tonic-gate xt = POP(DS);
870*0Sstevel@tonic-gate name = pop_a_string(env, &len);
871*0Sstevel@tonic-gate header(env, name, len, 0);
872*0Sstevel@tonic-gate COMPILE_TOKEN(&do_alias);
873*0Sstevel@tonic-gate COMPILE_TOKEN(xt);
874*0Sstevel@tonic-gate expose_acf(env, name);
875*0Sstevel@tonic-gate }
876*0Sstevel@tonic-gate
877*0Sstevel@tonic-gate void
f_error(fcode_env_t * env)878*0Sstevel@tonic-gate f_error(fcode_env_t *env)
879*0Sstevel@tonic-gate {
880*0Sstevel@tonic-gate #if 0
881*0Sstevel@tonic-gate env->interpretting = 0;
882*0Sstevel@tonic-gate log_message(MSG_ERROR, "Uniplemented FCODE token encountered %x\n",
883*0Sstevel@tonic-gate env->last_fcode);
884*0Sstevel@tonic-gate #else
885*0Sstevel@tonic-gate forth_abort(env, "Unimplemented FCODE token: 0x%x\n", env->last_fcode);
886*0Sstevel@tonic-gate #endif
887*0Sstevel@tonic-gate }
888*0Sstevel@tonic-gate
889*0Sstevel@tonic-gate static void
fcode_buffer_addr(fcode_env_t * env)890*0Sstevel@tonic-gate fcode_buffer_addr(fcode_env_t *env)
891*0Sstevel@tonic-gate {
892*0Sstevel@tonic-gate PUSH(DS, (fstack_t)(env->fcode_buffer));
893*0Sstevel@tonic-gate }
894*0Sstevel@tonic-gate
895*0Sstevel@tonic-gate #pragma init(_init)
896*0Sstevel@tonic-gate
897*0Sstevel@tonic-gate static void
_init(void)898*0Sstevel@tonic-gate _init(void)
899*0Sstevel@tonic-gate {
900*0Sstevel@tonic-gate fcode_env_t *env = initial_env;
901*0Sstevel@tonic-gate
902*0Sstevel@tonic-gate ASSERT(env);
903*0Sstevel@tonic-gate NOTICE;
904*0Sstevel@tonic-gate
905*0Sstevel@tonic-gate P1275(0x000, DEFINER, "end0", end0);
906*0Sstevel@tonic-gate P1275(0x010, DEFINER, "b(lit)", blit);
907*0Sstevel@tonic-gate P1275(0x011, DEFINER, "b(')", btick);
908*0Sstevel@tonic-gate P1275(0x012, DEFINER, "b(\")", bquote);
909*0Sstevel@tonic-gate P1275(0x013, DEFINER, "bbranch", bbranch);
910*0Sstevel@tonic-gate P1275(0x014, DEFINER, "b?branch", bqbranch);
911*0Sstevel@tonic-gate P1275(0x015, DEFINER, "b(loop)", bloop);
912*0Sstevel@tonic-gate P1275(0x016, DEFINER, "b(+loop)", bplusloop);
913*0Sstevel@tonic-gate P1275(0x017, DEFINER, "b(do)", bdo);
914*0Sstevel@tonic-gate P1275(0x018, DEFINER, "b(?do)", bqdo);
915*0Sstevel@tonic-gate P1275(0x01b, DEFINER, "b(leave)", bleave);
916*0Sstevel@tonic-gate P1275(0x01c, DEFINER, "b(of)", bof);
917*0Sstevel@tonic-gate
918*0Sstevel@tonic-gate P1275(0x087, 0, "fcode-revision", fcode_revision);
919*0Sstevel@tonic-gate
920*0Sstevel@tonic-gate P1275(0x08b, 0, "alloc-mem", alloc_mem);
921*0Sstevel@tonic-gate P1275(0x08c, 0, "free-mem", free_mem);
922*0Sstevel@tonic-gate
923*0Sstevel@tonic-gate P1275(0x0a4, 0, "-1", minus_one);
924*0Sstevel@tonic-gate P1275(0x0a5, 0, "0", zero);
925*0Sstevel@tonic-gate P1275(0x0a6, 0, "1", one);
926*0Sstevel@tonic-gate P1275(0x0a7, 0, "2", two);
927*0Sstevel@tonic-gate P1275(0x0a8, 0, "3", three);
928*0Sstevel@tonic-gate
929*0Sstevel@tonic-gate P1275(0x0ae, 0, "aligned", aligned);
930*0Sstevel@tonic-gate P1275(0x0b1, DEFINER, "b(<mark)", bmark);
931*0Sstevel@tonic-gate P1275(0x0b2, DEFINER, "b(>resolve)", bresolve);
932*0Sstevel@tonic-gate FCODE(0x0b3, 0, "set-token-table", fc_historical);
933*0Sstevel@tonic-gate FCODE(0x0b4, 0, "set-table", fc_historical);
934*0Sstevel@tonic-gate P1275(0x0b5, 0, "new-token", new_token);
935*0Sstevel@tonic-gate P1275(0x0b6, 0, "named-token", named_token);
936*0Sstevel@tonic-gate P1275(0x0b7, DEFINER, "b(:)", bcolon);
937*0Sstevel@tonic-gate P1275(0x0b8, DEFINER, "b(value)", bvalue);
938*0Sstevel@tonic-gate P1275(0x0b9, DEFINER, "b(variable)", bvariable);
939*0Sstevel@tonic-gate P1275(0x0ba, DEFINER, "b(constant)", bconstant);
940*0Sstevel@tonic-gate P1275(0x0bb, DEFINER, "b(create)", bcreate);
941*0Sstevel@tonic-gate P1275(0x0bc, DEFINER, "b(defer)", bdefer);
942*0Sstevel@tonic-gate P1275(0x0bd, 0, "b(buffer:)", bbuffer_colon);
943*0Sstevel@tonic-gate P1275(0x0be, 0, "b(field)", bfield);
944*0Sstevel@tonic-gate FCODE(0x0bf, 0, "b(code)", fc_historical);
945*0Sstevel@tonic-gate P1275(0x0c0, IMMEDIATE, "instance", instance);
946*0Sstevel@tonic-gate
947*0Sstevel@tonic-gate P1275(0x0c2, DEFINER, "b(;)", semi);
948*0Sstevel@tonic-gate P1275(0x0c3, DEFINER, "b(to)", bto);
949*0Sstevel@tonic-gate P1275(0x0c4, DEFINER, "b(case)", bcase);
950*0Sstevel@tonic-gate P1275(0x0c5, DEFINER, "b(endcase)", bendcase);
951*0Sstevel@tonic-gate P1275(0x0c6, DEFINER, "b(endof)", bendof);
952*0Sstevel@tonic-gate
953*0Sstevel@tonic-gate P1275(0x0ca, 0, "external-token", external_token);
954*0Sstevel@tonic-gate P1275(0x0cc, 0, "offset16", offset16);
955*0Sstevel@tonic-gate P1275(0x0cd, 0, "evaluate", evaluate);
956*0Sstevel@tonic-gate
957*0Sstevel@tonic-gate P1275(0x0da, 0, "get-token", get_token);
958*0Sstevel@tonic-gate P1275(0x0db, 0, "set-token", set_token);
959*0Sstevel@tonic-gate
960*0Sstevel@tonic-gate P1275(0x0f0, 0, "start0", start0);
961*0Sstevel@tonic-gate P1275(0x0f1, 0, "start1", start1);
962*0Sstevel@tonic-gate P1275(0x0f2, 0, "start2", start2);
963*0Sstevel@tonic-gate P1275(0x0f3, 0, "start4", start4);
964*0Sstevel@tonic-gate
965*0Sstevel@tonic-gate P1275(0x0fd, 0, "version1", version1);
966*0Sstevel@tonic-gate FCODE(0x0fe, 0, "4-byte-id", fc_historical);
967*0Sstevel@tonic-gate
968*0Sstevel@tonic-gate P1275(0x0ff, 0, "end1", end1);
969*0Sstevel@tonic-gate
970*0Sstevel@tonic-gate /* Call it "old-dma-alloc" so no one gets confused */
971*0Sstevel@tonic-gate FCODE(0x101, 0, "old-dma-alloc", fc_historical);
972*0Sstevel@tonic-gate
973*0Sstevel@tonic-gate FCODE(0x104, 0, "memmap", fc_historical);
974*0Sstevel@tonic-gate FCODE(0x105, 0, "free-virtual", fc_unimplemented);
975*0Sstevel@tonic-gate
976*0Sstevel@tonic-gate FCODE(0x106, 0, ">physical", fc_historical);
977*0Sstevel@tonic-gate
978*0Sstevel@tonic-gate FCODE(0x10f, 0, "my-params", fc_historical);
979*0Sstevel@tonic-gate
980*0Sstevel@tonic-gate P1275(0x11b, 0, "parse-2int", parse_two_int);
981*0Sstevel@tonic-gate
982*0Sstevel@tonic-gate FCODE(0x122, 0, "memory-test-suite", fc_unimplemented);
983*0Sstevel@tonic-gate FCODE(0x123, 0, "group-code", fc_historical);
984*0Sstevel@tonic-gate FCODE(0x124, 0, "mask", fc_unimplemented);
985*0Sstevel@tonic-gate
986*0Sstevel@tonic-gate FCODE(0x130, 0, "map-low", fc_unimplemented);
987*0Sstevel@tonic-gate FCODE(0x131, 0, "sbus-intr>cpu", fc_unimplemented);
988*0Sstevel@tonic-gate
989*0Sstevel@tonic-gate FCODE(0x170, 0, "fb1-draw-character", fc_historical);
990*0Sstevel@tonic-gate FCODE(0x171, 0, "fb1-reset-screen", fc_historical);
991*0Sstevel@tonic-gate FCODE(0x172, 0, "fb1-toggle-cursor", fc_historical);
992*0Sstevel@tonic-gate FCODE(0x173, 0, "fb1-erase-screen", fc_historical);
993*0Sstevel@tonic-gate FCODE(0x174, 0, "fb1-blink-screen", fc_historical);
994*0Sstevel@tonic-gate FCODE(0x175, 0, "fb1-invert-screen", fc_historical);
995*0Sstevel@tonic-gate FCODE(0x176, 0, "fb1-insert-characters", fc_historical);
996*0Sstevel@tonic-gate FCODE(0x177, 0, "fb1-delete-characters", fc_historical);
997*0Sstevel@tonic-gate FCODE(0x178, 0, "fb1-insert-lines", fc_historical);
998*0Sstevel@tonic-gate FCODE(0x179, 0, "fb1-delete-lines", fc_historical);
999*0Sstevel@tonic-gate FCODE(0x17a, 0, "fb1-draw-logo", fc_historical);
1000*0Sstevel@tonic-gate FCODE(0x17b, 0, "fb1-install", fc_historical);
1001*0Sstevel@tonic-gate FCODE(0x17c, 0, "fb1-slide-up", fc_historical);
1002*0Sstevel@tonic-gate
1003*0Sstevel@tonic-gate FCODE(0x190, 0, "VME-bus Support", fc_obsolete);
1004*0Sstevel@tonic-gate FCODE(0x191, 0, "VME-bus Support", fc_obsolete);
1005*0Sstevel@tonic-gate FCODE(0x192, 0, "VME-bus Support", fc_obsolete);
1006*0Sstevel@tonic-gate FCODE(0x193, 0, "VME-bus Support", fc_obsolete);
1007*0Sstevel@tonic-gate FCODE(0x194, 0, "VME-bus Support", fc_obsolete);
1008*0Sstevel@tonic-gate FCODE(0x195, 0, "VME-bus Support", fc_obsolete);
1009*0Sstevel@tonic-gate FCODE(0x196, 0, "VME-bus Support", fc_obsolete);
1010*0Sstevel@tonic-gate
1011*0Sstevel@tonic-gate FCODE(0x1a0, 0, "return-buffer", fc_historical);
1012*0Sstevel@tonic-gate FCODE(0x1a1, 0, "xmit-packet", fc_historical);
1013*0Sstevel@tonic-gate FCODE(0x1a2, 0, "poll-packet", fc_historical);
1014*0Sstevel@tonic-gate
1015*0Sstevel@tonic-gate FCODE(0x210, 0, "processor-type", fc_historical);
1016*0Sstevel@tonic-gate FCODE(0x211, 0, "firmware-version", fc_historical);
1017*0Sstevel@tonic-gate FCODE(0x212, 0, "fcode-version", fc_historical);
1018*0Sstevel@tonic-gate
1019*0Sstevel@tonic-gate FCODE(0x214, 0, "(is-user-word)", is_user_word);
1020*0Sstevel@tonic-gate FCODE(0x215, 0, "suspend-fcode", fc_unimplemented);
1021*0Sstevel@tonic-gate
1022*0Sstevel@tonic-gate FCODE(0x229, 0, "adr-mask", fc_historical);
1023*0Sstevel@tonic-gate
1024*0Sstevel@tonic-gate FCODE(0x238, 0, "probe", fc_historical);
1025*0Sstevel@tonic-gate FCODE(0x239, 0, "probe-virtual", fc_historical);
1026*0Sstevel@tonic-gate
1027*0Sstevel@tonic-gate P1275(0x23e, 0, "byte-load", byte_load);
1028*0Sstevel@tonic-gate
1029*0Sstevel@tonic-gate P1275(0x240, 0, "left-parse-string", left_parse_string);
1030*0Sstevel@tonic-gate FORTH(0, "fcode-buffer", fcode_buffer_addr);
1031*0Sstevel@tonic-gate }
1032