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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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