2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License, Version 1.0 only
2N/A * (the "License"). You may not use this file except in compliance
2N/A * with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright (c) 2000 by Sun Microsystems, Inc.
2N/A * All rights reserved.
2N/A */
2N/A
2N/A#ifndef _FCODE_ENGINE_H
2N/A#define _FCODE_ENGINE_H
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A#include <sys/types.h>
2N/A
2N/A#ifdef __cplusplus
2N/Aextern "C" {
2N/A#endif
2N/A
2N/A#define MAX_ORDER 32
2N/A#define CONVERT_HANDLES
2N/A
2N/A#ifdef BIGSTACK
2N/Atypedef long long fstack_t;
2N/Atypedef unsigned long long ufstack_t;
2N/A#else
2N/Atypedef long fstack_t;
2N/Atypedef unsigned long ufstack_t;
2N/A#endif
2N/Atypedef long *acf_t; /* pointer to execution token */
2N/Atypedef long token_t; /* sizeof a forth token */
2N/A
2N/A/* x@, x! type */
2N/Atypedef uint64_t u_xforth_t;
2N/Atypedef int64_t s_xforth_t;
2N/Atypedef uint64_t xforth_t;
2N/A
2N/A/* l@, l! type */
2N/Atypedef uint32_t u_lforth_t;
2N/Atypedef int32_t s_lforth_t;
2N/Atypedef uint32_t lforth_t;
2N/A
2N/A/* w@, w! type */
2N/Atypedef uint16_t u_wforth_t;
2N/Atypedef int16_t s_wforth_t;
2N/Atypedef uint16_t wforth_t;
2N/A
2N/A/* Double type */
2N/Atypedef uint64_t u_dforth_t;
2N/Atypedef int64_t s_dforth_t;
2N/Atypedef uint64_t dforth_t;
2N/A
2N/A/* Variable/Value/Constant type */
2N/Atypedef token_t variable_t;
2N/A
2N/Atypedef struct PROPERTY {
2N/A char *name;
2N/A uchar_t *data;
2N/A int size;
2N/A struct PROPERTY *next;
2N/A} prop_t;
2N/A
2N/Atypedef struct RESOURCE {
2N/A struct RESOURCE *next;
2N/A void *data;
2N/A} fc_resource_t;
2N/A
2N/A#define INIT_DATA 0
2N/A#define UINIT_DATA 1
2N/A
2N/Atypedef struct FCODE_ENV fcode_env_t;
2N/A
2N/Atypedef struct DEVICE_VECTOR {
2N/A /*
2N/A * If there is private data associated with a node this vector
2N/A * table contains the routines that will be called to augment the
2N/A * device.
2N/A * These two routines allow the interpreter to use a different
2N/A *
2N/A * Interface Note:
2N/A * Any routine installed here is assumed to have the standard forth
2N/A * call state. It must be a void function call taking a forth execution
2N/A * environment, returning any data on the stack. In general the
2N/A * vector call should have the same semantics as the original routine
2N/A * it is replacing. (see get_prop as an example).
2N/A *
2N/A * The caller has the responsibility of converting the resulting data
2N/A * back to a form it requires.
2N/A *
2N/A */
2N/A void (*get_package_prop)(fcode_env_t *);
2N/A void (*get_inherited_prop)(fcode_env_t *);
2N/A} device_vector_t;
2N/A
2N/Atypedef struct DEVICE device_t;
2N/A
2N/A#define MAX_MY_ADDR 4
2N/A
2N/Astruct DEVICE {
2N/A device_t *parent;
2N/A device_t *child;
2N/A device_t *peer;
2N/A prop_t *properties;
2N/A token_t *vocabulary;
2N/A fstack_t parent_adr_cells;
2N/A fstack_t my_space;
2N/A fstack_t my_addr[MAX_MY_ADDR];
2N/A fstack_t frame_buffer_adr;
2N/A int data_size[2];
2N/A token_t *init_data; /* initialised instance data */
2N/A void *private; /* app private data */
2N/A device_vector_t vectors;
2N/A};
2N/A
2N/Atypedef struct INSTANCE {
2N/A struct INSTANCE *parent;
2N/A device_t *device;
2N/A /*
2N/A * These are copies of the same structures from the device definition
2N/A * however changes here will be thrown away when the instance is
2N/A * destroyed.
2N/A */
2N/A char *my_args;
2N/A int my_args_len;
2N/A fstack_t my_space;
2N/A fstack_t my_addr[MAX_MY_ADDR];
2N/A fstack_t frame_buffer_adr;
2N/A token_t *data[2];
2N/A} instance_t;
2N/A
2N/Atypedef struct FCODE_TOKEN {
2N/A ulong_t flags;
2N/A char *name;
2N/A acf_t apf; /* pointer to acf in dictionary */
2N/A#ifdef DEBUG
2N/A int usage;
2N/A#endif
2N/A} fcode_token;
2N/A
2N/Atypedef struct {
2N/A char *buffer;
2N/A char *scanptr;
2N/A int maxlen;
2N/A int separator;
2N/A} input_typ;
2N/A
2N/Atypedef struct ERROR_FRAME {
2N/A struct ERROR_FRAME *next;
2N/A fstack_t *ds;
2N/A fstack_t *rs;
2N/A instance_t *myself;
2N/A token_t *ip;
2N/A fstack_t code;
2N/A} error_frame;
2N/A
2N/Astruct FCODE_ENV {
2N/A fcode_token *table; /* token table */
2N/A uchar_t *base; /* dictionary base */
2N/A uchar_t *here; /* current dp */
2N/A char *name; /* last name */
2N/A long level; /* level */
2N/A token_t *ip; /* instruction pointer */
2N/A token_t *wa; /* word address */
2N/A fstack_t *ds0; /* base of dats stack */
2N/A fstack_t *rs0; /* base of return stack */
2N/A fstack_t *ds; /* data stack base */
2N/A fstack_t *rs; /* return stack base */
2N/A variable_t num_base; /* current base */
2N/A token_t *current; /* current voc */
2N/A long order_depth;
2N/A token_t **order; /* Voc. search order */
2N/A token_t *lastlink; /* last forth def */
2N/A token_t *forth_voc_link; /* Storage location for 'forth' voc */
2N/A int last_token; /* last defined token */
2N/A device_t *root_node; /* root node */
2N/A device_t *attachment_pt;
2N/A device_t *current_device; /* */
2N/A instance_t *my_self; /* pointer to my data */
2N/A int offset_incr; /* size of FCODE token offsets */
2N/A error_frame *catch_frame;
2N/A uchar_t *fcode_buffer; /* pointer to fcode buffer */
2N/A uchar_t *fcode_ptr; /* pointer into fcode buffer */
2N/A uchar_t *last_fcode_ptr; /* pointer to last fcode fetched */
2N/A fstack_t last_fcode; /* last fcode# executed */
2N/A fstack_t last_error; /* last throw code executed */
2N/A int fcode_incr; /* space between bytecodes */
2N/A int interpretting;
2N/A variable_t state; /* compile or run? */
2N/A int fcode_debug;
2N/A int diagnostic_mode;
2N/A fstack_t instance_mode;
2N/A int interactive; /* DEBUG, interact variable */
2N/A int num_actions;
2N/A int action_count;
2N/A token_t *action_ptr;
2N/A int strict_fcode;
2N/A fstack_t control; /* control VM behaviour */
2N/A input_typ *input; /* input buffer pointer */
2N/A variable_t span;
2N/A char *picturebufpos; /* pictured string buffer position */
2N/A char *picturebuf; /* pictured string buffer */
2N/A int picturebuflen; /* pictured string buffer length */
2N/A variable_t output_column; /* output column# (#out) */
2N/A variable_t output_line; /* output line# (#line) */
2N/A#ifdef CONVERT_HANDLES
2N/A device_t *(*convert_phandle)(fcode_env_t *, fstack_t);
2N/A fstack_t (*revert_phandle)(fcode_env_t *, device_t *);
2N/A void (*allocate_phandle)(fcode_env_t *);
2N/A#endif
2N/A fc_resource_t *propbufs;
2N/A void *private; /* private data ptr for app use. */
2N/A};
2N/A
2N/A#define MAX_FCODE 0xfff /* max no. of Fcode entries in table */
2N/A
2N/A
2N/Atypedef unsigned char flag_t;
2N/A
2N/A#define DS (env->ds)
2N/A#define RS (env->rs)
2N/A#define TOS *DS
2N/A#define IP (env->ip)
2N/A#define WA (env->wa)
2N/A#define DEPTH (DS-env->ds0)
2N/A#define CURRENT (env->current)
2N/A#define ORDER (env->order)
2N/A#define BASE (env->base)
2N/A#define HERE (env->here)
2N/A#define CONTEXT env->order[env->order_depth]
2N/A#define MYSELF (env->my_self)
2N/A
2N/A#ifdef FCODE_INTERNAL
2N/A#include <fcode/proto.h>
2N/A#endif
2N/A#include <fcode/public.h>
2N/A
2N/A#define SIGN_SHIFT ((8*(sizeof (fstack_t)))-1)
2N/A#define SIGN_BIT (((ufstack_t)1)<<SIGN_SHIFT)
2N/A
2N/A/*
2N/A * Note that sizeof (token_t) MUST equal sizeof (token_t *). If it doesn't,
2N/A * many things will break.
2N/A */
2N/A#define _ALIGN(x, y) (((long)(x)) & ~(sizeof (y)-1))
2N/A#define TOKEN_ROUNDUP(x) _ALIGN((x + ((sizeof (token_t)-1))), token_t)
2N/A
2N/A#define min(x, y) ((x) < (y) ? (x) : (y))
2N/A#define max(x, y) ((x) > (y) ? (x) : (y))
2N/A
2N/A/* values for flag_t */
2N/A#define ANSI_WORD 0x01
2N/A#define P1275_WORD 0x02
2N/A#define FLAG_NONAME 0x04
2N/A#define IMMEDIATE 0x08
2N/A#define FLAG_VALUE 0x10
2N/A#define FLAG_DEBUG 0x20
2N/A#define DEFINER (FLAG_NONAME|IMMEDIATE)
2N/A
2N/A#define FORTH(fl, nm, fnc) define_word(env, fl, nm, fnc);
2N/A
2N/A#define LINK_TO_ACF(x) (((token_t *)(x))+1)
2N/A#define LINK_TO_FLAGS(x) (((flag_t *)(x))-1)
2N/A#define ACF_TO_LINK(x) (((token_t *)(x))-1)
2N/A#define ACF_TO_BODY(x) (((acf_t)(x))+1)
2N/A#define BODY_TO_LINK(x) (((acf_t)(x))-1)
2N/A#define BODY_TO_FLAGS(x) (((flag_t *)(BODY_TO_LINK(x))) - 1)
2N/A#define EXPOSE_ACF *((acf_t)env->current) = \
2N/A (token_t)(env->lastlink)
2N/A
2N/A#define COMPILE_TOKEN(x) PUSH(DS, (fstack_t)(x)); compile_comma(env);
2N/A#define CHECK_DEPTH(env, x, w) if ((x) > (env->ds - env->ds0)) \
2N/A forth_abort(env, "%s: stack underflow\n", w);
2N/A#define CHECK_RETURN_DEPTH(env, x, w) if ((x) > (env->rs - env->rs0)) \
2N/A forth_abort(env, "%s: return stack underflow\n", w);
2N/A
2N/A#define FCRP_NOERROR 0x80000000 /* fc_run_priv: no err msg. */
2N/A
2N/A#ifdef CONVERT_HANDLES
2N/A#define CONVERT_PHANDLE(e, x, y) x = env->convert_phandle(e, y)
2N/A#define REVERT_PHANDLE(e, x, y) x = env->revert_phandle(e, y)
2N/A#define ALLOCATE_PHANDLE(e) env->allocate_phandle(e)
2N/A#else
2N/A#define CONVERT_PHANDLE(e, x, y) x = (device_t *)(y)
2N/A#define REVERT_PHANDLE(e, x, y) x = (fstack_t)(y)
2N/A#define ALLOCATE_PHANDLE(e)
2N/A#endif
2N/A
2N/Aextern fcode_env_t *env;
2N/Aextern int dict_size;
2N/Aextern int in_forth_abort;
2N/Aextern int stack_size;
2N/Aextern token_t value_defines[][3];
2N/Aextern void (*bbranch_ptrs[3])(fcode_env_t *);
2N/Aextern void (*blit_ptr)(fcode_env_t *);
2N/Aextern void (*create_ptr)(fcode_env_t *);
2N/Aextern void (*do_bdo_ptr)(fcode_env_t *);
2N/Aextern void (*do_bqdo_ptr)(fcode_env_t *);
2N/Aextern void (*do_leave_ptr)(fcode_env_t *);
2N/Aextern void (*do_loop_ptr)(fcode_env_t *);
2N/Aextern void (*do_ploop_ptr)(fcode_env_t *);
2N/Aextern void (*does_ptr)(fcode_env_t *);
2N/Aextern void (*quote_ptr)(fcode_env_t *);
2N/Aextern void (*quote_ptr)(fcode_env_t *);
2N/Aextern void (*semi_ptr)(fcode_env_t *);
2N/Aextern void (*tlit_ptr)(fcode_env_t *);
2N/Aextern void (*to_ptr)(fcode_env_t *);
2N/Aextern void (*to_ptr)(fcode_env_t *);
2N/A
2N/A#ifdef __cplusplus
2N/A}
2N/A#endif
2N/A
2N/A#endif /* _FCODE_ENGINE_H */