1/* 2 * Copyright (c) 2002 by The XFree86 Project, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 * 22 * Except as contained in this notice, the name of the XFree86 Project shall 23 * not be used in advertising or otherwise to promote the sale, use or other 24 * dealings in this Software without prior written authorization from the 25 * XFree86 Project. 26 * 27 * Author: Paulo César Pereira de Andrade 28 */ 29 30/* $XFree86: xc/programs/xedit/lisp/bytecode.h,v 1.5tsi Exp $ */ 31 32#include "lisp/private.h" 33 34#ifndef Lisp_Bytecode_h 35#define Lisp_Bytecode_h 36 37/* Number of arguments for &REST functions with no side effects, 38 * i.e. does not need to allocate new cells to build argument list. 39 * If this value is changed, it is also required to add more 40 * XBC_BCONS? opcodes and change ExecuteBytecode() */ 41#define MAX_BCONS 8 42 43typedef enum { 44 XBP_CONSP, 45 XBP_LISTP, 46 XBP_NUMBERP 47} LispBytePredicate; 48 49typedef enum { 50 XBC_NOOP, 51 52 XBC_INV, /* If NIL loaded, change to T else to NIL */ 53 XBC_NIL, /* Load NIL */ 54 XBC_T, /* Load T */ 55 56 XBC_PRED, /* Preffix for predicate test */ 57 /* Followed by byte indicating test */ 58 59 XBC_CAR, /* Set loaded value to it's car */ 60 XBC_CDR, /* Set loaded value to it's cdr */ 61 62 XBC_CAR_SET, /* Set local variable to CAR or CDR of loaded value */ 63 XBC_CDR_SET, 64 /* Offset of local variable follows */ 65 66 /* Sets C[AD]R of top of builtin stack with 67 * loaded value and pop builtin stack */ 68 XBC_RPLACA, 69 XBC_RPLACD, 70 71 /* Push only one argument in builtin stack, and call directly 72 * LispObjectCompare without the need of pushing the second arguument */ 73 XBC_EQ, 74 XBC_EQL, 75 XBC_EQUAL, 76 XBC_EQUALP, 77 78 XBC_LENGTH, 79 XBC_LAST, 80 XBC_NTHCDR, 81 82 XBC_CAR_PUSH, /* Pushes CAR or CDR of loaded value to builtin stack */ 83 XBC_CDR_PUSH, 84 85 XBC_PUSH, /* Push argument in builtin stack */ 86 XBC_PUSH_NIL, /* Pushes NIL in builtin stack */ 87 XBC_PUSH_UNSPEC, /* Pushes #<UNSPEC> in builtin stack */ 88 XBC_PUSH_T, /* Pushes T in builtin stack */ 89 XBC_PUSH_NIL_N, /* Pushes NIL in the builtin stack N times */ 90 XBC_PUSH_UNSPEC_N, /* Pushes #<UNSPEC> in the builtin stack N times */ 91 92 93 /* The builtin stack base is saved when entering the bytecode 94 * interpreter, and the bytecode does not reenter from builtin 95 * functions, yet, so there is no need, for XBC_BSAVE and 96 * XBC_BREST instructions */ 97 98 XBC_LET, /* Push loaded value to stack */ 99 XBC_LETX, /* Push loaded value to stack and bind */ 100 /* Next byte(s) are the symbol offset */ 101 XBC_LET_NIL, /* Push loaded value to stack */ 102 XBC_LETX_NIL, /* Push loaded value to stack and bind */ 103 /* Next byte(s) are the symbol offset */ 104 105 XBC_LETBIND, /* Bind locally added variables */ 106 /* Followed by number of symbols to bind */ 107 108 XBC_UNLET, /* Unbind locally binded variables */ 109 /* Followed by number of symbols to unbind */ 110 111 XBC_LOAD, /* Load argument already from the stack */ 112 /* Followed by offset follows the opcode */ 113 XBC_LOAD_LET, /* Load argument and push */ 114 XBC_LOAD_LETX, /* Load argument, push and bind */ 115 /* Followed by a short and the atom to be bound */ 116 XBC_LOAD_PUSH, 117 118 XBC_LOADCON, /* Load a literal constant */ 119 /* Next bytes are the constant object */ 120 XBC_LOADCON_LET, /* Load a literal constant and push */ 121 XBC_LOADCON_LETX, /* Load a literal constant, push and bind */ 122 /* Followed by object constant and symbol to be bound */ 123 XBC_LOADCON_PUSH, 124 125 /* Load CAR or CDR of local variable */ 126 XBC_LOAD_CAR, 127 XBC_LOAD_CDR, 128 129 /* Change local variable value to it's CAR or CDR */ 130 XBC_LOAD_CAR_STORE, 131 XBC_LOAD_CDR_STORE, 132 133 XBC_LOADCON_SET, 134 /* Followed by constant offset and local variable offset */ 135 136 XBC_LOADSYM, /* Load object symbol value */ 137 /* The object atom pointer follows de opcode */ 138 XBC_LOADSYM_LET, /* Load object symbol value and push */ 139 XBC_LOADSYM_LETX, /* Load object symbol value, push and bind */ 140 /* The symbol atom name and bounded atom name to be bound follows */ 141 XBC_LOADSYM_PUSH, 142 143 XBC_LOAD_SET, /* Set value of local variable to the value of another */ 144 /* Followed by two shorts */ 145 XBC_LOAD_CAR_SET, /* Like LOAD_SET, but apply CAR or CDR in the value */ 146 XBC_LOAD_CDR_SET, 147 148 XBC_SET, /* Change value of local variable */ 149 /* A short integer with relative offset follows opcode */ 150 XBC_SETSYM, /* Change value of symbol */ 151 /* The atom symbol pointer follows opcode */ 152 153 XBC_SET_NIL, /* Like XBC_SET but sets the local variable to NIL */ 154 155 XBC_CALL, /* Call builtin function */ 156 /* 1 byte follows telling how many arguments to use */ 157 /* LispBuiltin pointer follows opcode */ 158 159 XBC_CALL_SET, 160 /* Like BCALL, but also followed by an short index of local variable */ 161 162 XBC_BYTECALL, /* Call bytecode */ 163 /* 1 byte for number of arguments */ 164 /* 1 byte for index in bytecode table */ 165 166 XBC_FUNCALL, 167 /* Opcode followed by function and arguments objects, to 168 * be evaluated at run time, as it was not resolved at 169 * bytecode generation time (or is not implemented in 170 * the bytecode compiler) */ 171 172 173 XBC_LETREC, /* Recursive function call */ 174 /* 1 byte follows telling how many arguments the funtion receives */ 175 176 /* Helper for math functions. Uses a preallocated CONS, 177 * setting it's CAR to the loaded value, and in the same step 178 * pushes the CONS to the builtin stack */ 179 XBC_BCONS, 180 /* Like BCONS but it is a list of 2 arguments, first argument 181 * is saved on the stack, replace with list of 2 arguments */ 182 XBC_BCONS1, 183 /* Like BCONS1 but it is a list of 3 arguments, first arguments 184 * are saved on the stack, replace with list of first stack 185 * argument with list or 3 arguments, and pop stack */ 186 XBC_BCONS2, 187 XBC_BCONS3, 188 XBC_BCONS4, 189 XBC_BCONS5, 190 XBC_BCONS6, 191 XBC_BCONS7, 192 193 /* Build a CONS */ 194 XBC_CCONS, /* Make CONS of two constants */ 195 /* Constants follow opcode */ 196 XBC_CSTAR, /* Save the CAR of the CONS */ 197 XBC_CFINI, /* Loaded value is the CDR */ 198 199 /* These are to help in interactively building lists */ 200 XBC_LSTAR, /* Start building a list in the gc protected stack */ 201 XBC_LCONS, /* Add loaded object to list */ 202 XBC_LFINI, /* List is finished */ 203 204 /* Inconditional jumps */ 205 XBC_JUMP, /* Jump relative to following signed int */ 206 207 /* Conditional jumps, if true */ 208 XBC_JUMPT, /* Jump relative to following signed int */ 209 210 /* Conditional jumps, if false */ 211 XBC_JUMPNIL, /* Jump relative to following signed int */ 212 213 /* Structure field access and type check */ 214 XBC_STRUCT, 215 XBC_STRUCTP, 216 217 XBC_RETURN /* Resume bytecode execution */ 218} LispByteOpcode; 219 220 221struct _LispBytecode { 222 unsigned char *code; /* Bytecode data */ 223 long length; /* length of bytecode stream */ 224}; 225 226/* 227 * Prototypes 228 */ 229void LispBytecodeInit(void); 230 231LispObj *Lisp_Compile(LispBuiltin*); 232LispObj *Lisp_Disassemble(LispBuiltin*); 233 234LispObj *LispCompileForm(LispObj*); 235LispObj *LispExecuteBytecode(LispObj*); 236 237void Com_And(LispCom*, LispBuiltin*); 238void Com_Block(LispCom*, LispBuiltin*); 239void Com_C_r(LispCom*, LispBuiltin*); 240void Com_Cond(LispCom*, LispBuiltin*); 241void Com_Cons(LispCom*, LispBuiltin*); 242void Com_Consp(LispCom*, LispBuiltin*); 243void Com_Dolist(LispCom*, LispBuiltin*); 244void Com_Eq(LispCom*, LispBuiltin*); 245void Com_Go(LispCom*, LispBuiltin*); 246void Com_If(LispCom*, LispBuiltin*); 247void Com_Last(LispCom*, LispBuiltin*); 248void Com_Length(LispCom*, LispBuiltin*); 249void Com_Let(LispCom*, LispBuiltin*); 250void Com_Letx(LispCom*, LispBuiltin*); 251void Com_Listp(LispCom*, LispBuiltin*); 252void Com_Loop(LispCom*, LispBuiltin*); 253void Com_Nthcdr(LispCom*, LispBuiltin*); 254void Com_Null(LispCom*, LispBuiltin*); 255void Com_Numberp(LispCom*, LispBuiltin*); 256void Com_Or(LispCom*, LispBuiltin*); 257void Com_Progn(LispCom*, LispBuiltin*); 258void Com_Return(LispCom*, LispBuiltin*); 259void Com_ReturnFrom(LispCom*, LispBuiltin*); 260void Com_Rplac_(LispCom*, LispBuiltin*); 261void Com_Setq(LispCom*, LispBuiltin*); 262void Com_Tagbody(LispCom*, LispBuiltin*); 263void Com_Unless(LispCom*, LispBuiltin*); 264void Com_Until(LispCom*, LispBuiltin*); 265void Com_When(LispCom*, LispBuiltin*); 266void Com_While(LispCom*, LispBuiltin*); 267 268#endif /* Lisp_Bytecode_h */ 269