diff --git a/src/lex.c b/src/lex.c
index f35e9004d32f15a20b1070a2e3f5f9326cf0d4bb..5143deb4279c0e2aadd22ba30356ecc8984e8242 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -2,497 +2,19 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: lex.c,v 1.116 2003/11/13 00:24:08 mast Exp $
+|| $Id: lex.c,v 1.117 2003/11/14 10:12:29 mast Exp $
 */
 
 #include "global.h"
-RCSID("$Id: lex.c,v 1.116 2003/11/13 00:24:08 mast Exp $");
+RCSID("$Id: lex.c,v 1.117 2003/11/14 10:12:29 mast Exp $");
 #include "language.h"
-#include "array.h"
 #include "lex.h"
-#include "stralloc.h"
-#include "dynamic_buffer.h"
-#include "constants.h"
 #include "stuff.h"
-#include "pike_memory.h"
-#include "interpret.h"
-#include "pike_error.h"
-#include "object.h"
-#include "las.h"
-#include "operators.h"
-#include "opcodes.h"
-#include "builtin_functions.h"
-#include "main.h"
-#include "mapping.h"
-#include "pikecode.h"
-
-#include "pike_macros.h"
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
 
 #include <ctype.h>
-#include <math.h>
-#include <fcntl.h>
-#include <errno.h>
-#include "time_stuff.h"
 
 #define LEXDEBUG 0
 
-#ifdef INSTR_PROFILING
-
-/*
- * If you have a 64 bit machine and 15+ Gb memory, this
- * routine should handle -p4 nicely. -Hubbe
- * (-p3 only requires ~38Mb on a 32bit machine)
- */
-
-struct instr_counter
-{
-  long runned;
-  struct instr_counter* next[256];
-};
-
-int last_instruction[256];
-struct instr_counter *instr_counter_storage;
-
-struct instr_counter *init_instr_storage_pointers(int depth)
-{
-  int e;
-  struct instr_counter *d;
-  if(!depth) return 0;
-  d=ALLOC_STRUCT(instr_counter);
-  if(!d)
-  {
-    fprintf(stderr,"-p%d: out of memory.\n",p_flag);
-    exit(2);
-  }
-  dmalloc_accept_leak(d);
-  d->runned=0;
-  for(e=0;e<F_MAX_OPCODE-F_OFFSET;e++)
-    d->next[e]=init_instr_storage_pointers(depth-1);
-  return d;
-}
-
-void add_runned(PIKE_INSTR_T instr)
-{
-  int e;
-  struct instr_counter **tmp=&instr_counter_storage;
-
-  for(e=0;e<p_flag;e++)
-  {
-    tmp[0]->runned++;
-    tmp=tmp[0]->next + last_instruction[e];
-    last_instruction[e]=last_instruction[e+1];
-  }
-#ifndef HAVE_COMPUTED_GOTO
-  ((char **)(tmp))[0]++;
-#endif /* !HAVE_COMPUTED_GOTO */
-  last_instruction[e]=instr;
-}
-
-void present_runned(struct instr_counter *d, int depth, int maxdepth)
-{
-  int e;
-  if(depth == maxdepth)
-  {
-    long runned = depth < p_flag ? d->runned : (long)d;
-    if(!runned) return;
-    fprintf(stderr,"%010ld @%d@: ",runned,maxdepth);
-    for(e=0;e<depth;e++)
-    {
-      if(e) fprintf(stderr," :: ");
-      fprintf(stderr,"%s",
-	      low_get_f_name(last_instruction[e] + F_OFFSET,0));
-    }
-    fprintf(stderr,"\n");
-  }else{
-    for(e=0;e<F_MAX_OPCODE-F_OFFSET;e++)
-    {
-      last_instruction[depth]=e;
-      present_runned(d->next[e],depth+1, maxdepth);
-    }
-  }
-}
-
-#endif
-
-void exit_lex(void)
-{
-#ifdef PIKE_DEBUG
-  if(p_flag)
-  {
-    extern void present_constant_profiling(void);
-    int e;
-    present_constant_profiling();
-
-    fprintf(stderr,"Opcode compiles: (opcode, compiled)\n");
-    for(e=0;e<F_MAX_OPCODE-F_OFFSET;e++)
-    {
-      fprintf(stderr,"%08ld;;%-30s\n",
-	      (long)instrs[e].compiles,
-	      low_get_f_name(e+F_OFFSET,0));
-    }
-
-#ifdef INSTR_PROFILING
-    for(e=0;e<=p_flag;e++)
-    {
-      fprintf(stderr,"Opcode x %d usage:\n",e);
-      present_runned(instr_counter_storage, 0, e);
-    }
-  }
-#endif
-#endif
-}
-
-#ifdef PIKE_USE_MACHINE_CODE
-#define ADDR(X) , (void *)PIKE_CONCAT(opcode_,X)
-#define NULLADDR , 0
-#define ALIASADDR(X)	, (void *)(X)
-
-#define OPCODE0(OP,DESC,FLAGS) void PIKE_CONCAT(opcode_,OP)(void);
-#define OPCODE1(OP,DESC,FLAGS) void PIKE_CONCAT(opcode_,OP)(INT32);
-#define OPCODE2(OP,DESC,FLAGS) void PIKE_CONCAT(opcode_,OP)(INT32,INT32);
-
-#ifdef OPCODE_RETURN_JUMPADDR
-#define OPCODE0_JUMP(OP,DESC,FLAGS) void *PIKE_CONCAT(jump_opcode_,OP)(void);
-#define OPCODE1_JUMP(OP,DESC,FLAGS) void *PIKE_CONCAT(jump_opcode_,OP)(INT32);
-#define OPCODE2_JUMP(OP,DESC,FLAGS) void *PIKE_CONCAT(jump_opcode_,OP)(INT32,INT32);
-#define JUMPADDR(X) , (void *)PIKE_CONCAT(jump_opcode_,X)
-#else  /* !OPCODE_RETURN_JUMPADDR */
-#define OPCODE0_JUMP(OP, DESC, FLAGS) OPCODE0(OP, DESC, FLAGS)
-#define OPCODE1_JUMP(OP, DESC, FLAGS) OPCODE1(OP, DESC, FLAGS)
-#define OPCODE2_JUMP(OP, DESC, FLAGS) OPCODE2(OP, DESC, FLAGS)
-#define JUMPADDR(X) ADDR(X)
-#endif	/* !OPCODE_RETURN_JUMPADDR */
-
-#define OPCODE0_PTRJUMP(OP,DESC,FLAGS) OPCODE0_JUMP(OP, DESC, FLAGS)
-#define OPCODE1_PTRJUMP(OP,DESC,FLAGS) OPCODE1_JUMP(OP, DESC, FLAGS)
-#define OPCODE2_PTRJUMP(OP,DESC,FLAGS) OPCODE2_JUMP(OP, DESC, FLAGS)
-
-#define OPCODE0_RETURN(OP,DESC,FLAGS) OPCODE0_JUMP(OP, DESC, FLAGS)
-#define OPCODE1_RETURN(OP,DESC,FLAGS) OPCODE1_JUMP(OP, DESC, FLAGS)
-#define OPCODE2_RETURN(OP,DESC,FLAGS) OPCODE2_JUMP(OP, DESC, FLAGS)
-
-#define OPCODE0_ALIAS(OP, DESC, FLAGS, ADDR)
-#define OPCODE1_ALIAS(OP, DESC, FLAGS, ADDR)
-#define OPCODE2_ALIAS(OP, DESC, FLAGS, ADDR)
-
-#ifdef OPCODE_INLINE_BRANCH
-#define OPCODE0_BRANCH(OP,DESC,FLAGS) int PIKE_CONCAT(test_opcode_,OP)(void);
-#define OPCODE1_BRANCH(OP,DESC,FLAGS) int PIKE_CONCAT(test_opcode_,OP)(INT32);
-#define OPCODE2_BRANCH(OP,DESC,FLAGS) int PIKE_CONCAT(test_opcode_,OP)(INT32,INT32);
-#define BRANCHADDR(X) , (void *)PIKE_CONCAT(test_opcode_,X)
-#else /* !OPCODE_INLINE_BRANCH */
-#define OPCODE0_BRANCH		OPCODE0_PTRJUMP
-#define OPCODE1_BRANCH		OPCODE1_PTRJUMP
-#define OPCODE2_BRANCH		OPCODE2_PTRJUMP
-#define BRANCHADDR(X) JUMPADDR(X)
-#endif /* OPCODE_INLINE_BRANCH */
-
-#define OPCODE0_TAIL(OP,DESC,FLAGS) OPCODE0(OP,DESC,FLAGS)
-#define OPCODE1_TAIL(OP,DESC,FLAGS) OPCODE1(OP,DESC,FLAGS)
-#define OPCODE2_TAIL(OP,DESC,FLAGS) OPCODE2(OP,DESC,FLAGS)
-#define OPCODE0_TAILJUMP(OP,DESC,FLAGS) OPCODE0_JUMP(OP,DESC,FLAGS)
-#define OPCODE1_TAILJUMP(OP,DESC,FLAGS) OPCODE1_JUMP(OP,DESC,FLAGS)
-#define OPCODE2_TAILJUMP(OP,DESC,FLAGS) OPCODE2_JUMP(OP,DESC,FLAGS)
-#define OPCODE0_TAILPTRJUMP(OP,DESC,FLAGS) OPCODE0_PTRJUMP(OP, DESC, FLAGS)
-#define OPCODE1_TAILPTRJUMP(OP,DESC,FLAGS) OPCODE1_PTRJUMP(OP, DESC, FLAGS)
-#define OPCODE2_TAILPTRJUMP(OP,DESC,FLAGS) OPCODE2_PTRJUMP(OP, DESC, FLAGS)
-#define OPCODE0_TAILRETURN(OP,DESC,FLAGS) OPCODE0_RETURN(OP, DESC, FLAGS)
-#define OPCODE1_TAILRETURN(OP,DESC,FLAGS) OPCODE1_RETURN(OP, DESC, FLAGS)
-#define OPCODE2_TAILRETURN(OP,DESC,FLAGS) OPCODE2_RETURN(OP, DESC, FLAGS)
-#define OPCODE0_TAILBRANCH(OP,DESC,FLAGS) OPCODE0_BRANCH(OP,DESC,FLAGS)
-#define OPCODE1_TAILBRANCH(OP,DESC,FLAGS) OPCODE1_BRANCH(OP,DESC,FLAGS)
-#define OPCODE2_TAILBRANCH(OP,DESC,FLAGS) OPCODE2_BRANCH(OP,DESC,FLAGS)
-
-#include "interpret_protos.h"
-
-#undef OPCODE0
-#undef OPCODE1
-#undef OPCODE2
-#undef OPCODE0_TAIL
-#undef OPCODE1_TAIL
-#undef OPCODE2_TAIL
-
-#undef OPCODE0_JUMP
-#undef OPCODE1_JUMP
-#undef OPCODE2_JUMP
-#undef OPCODE0_TAILJUMP
-#undef OPCODE1_TAILJUMP
-#undef OPCODE2_TAILJUMP
-
-#undef OPCODE0_PTRJUMP
-#undef OPCODE1_PTRJUMP
-#undef OPCODE2_PTRJUMP
-#undef OPCODE0_TAILPTRJUMP
-#undef OPCODE1_TAILPTRJUMP
-#undef OPCODE2_TAILPTRJUMP
-
-#undef OPCODE0_RETURN
-#undef OPCODE1_RETURN
-#undef OPCODE2_RETURN
-#undef OPCODE0_TAILRETURN
-#undef OPCODE1_TAILRETURN
-#undef OPCODE2_TAILRETURN
-
-#undef OPCODE0_ALIAS
-#undef OPCODE1_ALIAS
-#undef OPCODE2_ALIAS
-
-#undef OPCODE0_BRANCH
-#undef OPCODE1_BRANCH
-#undef OPCODE2_BRANCH
-#undef OPCODE0_TAILBRANCH
-#undef OPCODE1_TAILBRANCH
-#undef OPCODE2_TAILBRANCH
-
-#else
-#define ADDR(X)
-#define BRANCHADDR(X)
-#define JUMPADDR(X)
-#define NULLADDR
-#define ALIASADDR(X)
-#endif
-
-#define OPCODE0(OP,DESC,FLAGS) { DESC, OP, FLAGS ADDR(OP) },
-#define OPCODE1(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_HASARG ADDR(OP) },
-#define OPCODE2(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_TWO_ARGS ADDR(OP) },
-#define OPCODE0_TAIL(OP,DESC,FLAGS) OPCODE0(OP,DESC,FLAGS)
-#define OPCODE1_TAIL(OP,DESC,FLAGS) OPCODE1(OP,DESC,FLAGS)
-#define OPCODE2_TAIL(OP,DESC,FLAGS) OPCODE2(OP,DESC,FLAGS)
-
-#define OPCODE0_PTRJUMP(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISPTRJUMP JUMPADDR(OP) },
-#define OPCODE1_PTRJUMP(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISPTRJUMPARG JUMPADDR(OP) },
-#define OPCODE2_PTRJUMP(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISPTRJUMPARGS JUMPADDR(OP) },
-#define OPCODE0_TAILPTRJUMP(OP,DESC,FLAGS) OPCODE0_PTRJUMP(OP,DESC,FLAGS)
-#define OPCODE1_TAILPTRJUMP(OP,DESC,FLAGS) OPCODE1_PTRJUMP(OP,DESC,FLAGS)
-#define OPCODE2_TAILPTRJUMP(OP,DESC,FLAGS) OPCODE2_PTRJUMP(OP,DESC,FLAGS)
-
-#define OPCODE0_JUMP(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISJUMP JUMPADDR(OP) },
-#define OPCODE1_JUMP(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISJUMPARG JUMPADDR(OP) },
-#define OPCODE2_JUMP(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISJUMPARGS JUMPADDR(OP) },
-#define OPCODE0_TAILJUMP(OP, DESC, FLAGS) OPCODE0_JUMP(OP,DESC,FLAGS)
-#define OPCODE1_TAILJUMP(OP, DESC, FLAGS) OPCODE1_JUMP(OP,DESC,FLAGS)
-#define OPCODE2_TAILJUMP(OP, DESC, FLAGS) OPCODE2_JUMP(OP,DESC,FLAGS)
-
-#define OPCODE0_RETURN(OP, DESC, FLAGS) OPCODE0_JUMP(OP,DESC,FLAGS)
-#define OPCODE1_RETURN(OP, DESC, FLAGS) OPCODE1_JUMP(OP,DESC,FLAGS)
-#define OPCODE2_RETURN(OP, DESC, FLAGS) OPCODE2_JUMP(OP,DESC,FLAGS)
-#define OPCODE0_TAILRETURN(OP, DESC, FLAGS) OPCODE0_RETURN(OP,DESC,FLAGS)
-#define OPCODE1_TAILRETURN(OP, DESC, FLAGS) OPCODE1_RETURN(OP,DESC,FLAGS)
-#define OPCODE2_TAILRETURN(OP, DESC, FLAGS) OPCODE2_RETURN(OP,DESC,FLAGS)
-
-#define OPCODE0_ALIAS(OP, DESC, FLAGS, A) { DESC, OP, FLAGS ALIASADDR(A) },
-#define OPCODE1_ALIAS(OP, DESC, FLAGS, A) { DESC, OP, FLAGS | I_HASARG ALIASADDR(A) },
-#define OPCODE2_ALIAS(OP, DESC, FLAGS, A) { DESC, OP, FLAGS | I_TWO_ARGS ALIASADDR(A) },
-
-#define OPCODE0_BRANCH(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISBRANCH BRANCHADDR(OP) },
-#define OPCODE1_BRANCH(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISBRANCHARG BRANCHADDR(OP) },
-#define OPCODE2_BRANCH(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISBRANCHARGS BRANCHADDR(OP) },
-#define OPCODE0_TAILBRANCH(OP,DESC,FLAGS) OPCODE0_BRANCH(OP,DESC,FLAGS)
-#define OPCODE1_TAILBRANCH(OP,DESC,FLAGS) OPCODE1_BRANCH(OP,DESC,FLAGS)
-#define OPCODE2_TAILBRANCH(OP,DESC,FLAGS) OPCODE2_BRANCH(OP,DESC,FLAGS)
-
-#define LEXER
-
-struct keyword instr_names[]=
-{
-#ifndef PIKE_PRECOMPILER
-#include "interpret_protos.h"
-#endif /* !PIKE_PRECOMPILER */
-{ "%=",			F_MOD_EQ,0 NULLADDR },	
-{ "&=",			F_AND_EQ,0 NULLADDR },	
-{ "|=",			F_OR_EQ,0 NULLADDR },	
-{ "*=",			F_MULT_EQ,0 NULLADDR },	
-{ "+=",			F_ADD_EQ,0 NULLADDR },	
-{ "-=",			F_SUB_EQ,0 NULLADDR },	
-{ "/=",			F_DIV_EQ,0 NULLADDR },	
-{ "<<=",		F_LSH_EQ,0 NULLADDR },	
-{ ">>=",		F_RSH_EQ,0 NULLADDR },	
-{ "^=",			F_XOR_EQ,0 NULLADDR },	
-{ "arg+=1024",		F_PREFIX_1024,0 NULLADDR },
-{ "arg+=256",		F_PREFIX_256,0 NULLADDR },
-{ "arg+=256*X",		F_PREFIX_CHARX256,0 NULLADDR },
-{ "arg+=256*XX",	F_PREFIX_WORDX256,0 NULLADDR },
-{ "arg+=256*XXX",	F_PREFIX_24BITX256,0 NULLADDR },
-{ "arg+=512",		F_PREFIX_512,0 NULLADDR },
-{ "arg+=768",		F_PREFIX_768,0 NULLADDR },
-
-{ "arg+=1024",		F_PREFIX2_1024,0 NULLADDR },
-{ "arg+=256",		F_PREFIX2_256,0 NULLADDR },
-{ "arg+=256*X",		F_PREFIX2_CHARX256,0 NULLADDR },
-{ "arg+=256*XX",	F_PREFIX2_WORDX256,0 NULLADDR },
-{ "arg+=256*XXX",	F_PREFIX2_24BITX256,0 NULLADDR },
-{ "arg+=512",		F_PREFIX2_512,0 NULLADDR },
-{ "arg+=768",		F_PREFIX2_768,0 NULLADDR },
-
-{ "break",		F_BREAK,0 NULLADDR },	
-{ "case",		F_CASE,0 NULLADDR },	
-{ "continue",		F_CONTINUE,0 NULLADDR },	
-{ "default",		F_DEFAULT,0 NULLADDR },	
-{ "do-while",		F_DO,0 NULLADDR },	
-{ "for",		F_FOR,0 NULLADDR },
-
-{ "pointer",		F_POINTER, I_ISPOINTER NULLADDR },
-{ "data",		F_DATA, I_DATA NULLADDR },
-{ "byte",		F_BYTE, I_DATA NULLADDR },
-{ "lvalue_list",	F_LVALUE_LIST,0 NULLADDR },	
-{ "label",		F_LABEL,I_HASARG NULLADDR },
-{ "align",		F_ALIGN, I_HASARG NULLADDR },
-{ "nop",                F_NOP,0 NULLADDR },
-{ "entry",		F_ENTRY,0 NULLADDR },
-{ "function start",     F_START_FUNCTION,0 NULLADDR },
-{ "notreached!",        F_NOTREACHED, 0 NULLADDR },
-};
-
-struct instr instrs[F_MAX_INSTR - F_OFFSET];
-
-struct reserved
-{
-  struct hash_entry link;
-  int token;
-};
-
-void init_lex()
-{
-  unsigned int i;
-#ifdef PIKE_DEBUG
-  int fatal_later=0;
-#ifdef INSTR_PROFILING
-  instr_counter_storage=init_instr_storage_pointers(p_flag);
-#endif
-#endif
-
-  for(i=0; i<NELEM(instr_names);i++)
-  {
-#ifdef PIKE_DEBUG
-    if(instr_names[i].token >= F_MAX_INSTR)
-    {
-      fprintf(stderr,"Error in instr_names[%u]\n\n",i);
-      fatal_later++;
-    }
-
-    if(instrs[instr_names[i].token - F_OFFSET].name)
-    {
-      fprintf(stderr,"Duplicate name for %s\n",instr_names[i].word);
-      fatal_later++;
-    }
-#endif
-
-    instrs[instr_names[i].token - F_OFFSET].name = instr_names[i].word;
-    instrs[instr_names[i].token - F_OFFSET].flags=instr_names[i].flags;
-#ifdef PIKE_USE_MACHINE_CODE
-    instrs[instr_names[i].token - F_OFFSET].address=instr_names[i].address;
-#endif
-  }
-
-#ifdef PIKE_DEBUG
-  for(i=1; i<F_MAX_OPCODE-F_OFFSET;i++)
-  {
-    if(!instrs[i].name)
-    {
-      fprintf(stderr,"Opcode %d does not have a name.\n",i);
-      fatal_later++;
-    }
-  }
-  if(fatal_later)
-    Pike_fatal("Found %d errors in instrs.\n",fatal_later);
-
-#endif
-
-}
-
-char *low_get_f_name(int n,struct program *p)
-{
-  static char buf[30];
-  
-  if (n<F_MAX_OPCODE && instrs[n-F_OFFSET].name)
-  {
-    return instrs[n-F_OFFSET].name;
-  }else if(n >= F_MAX_OPCODE) {
-    if(p &&
-       (int)p->num_constants > (int)(n-F_MAX_OPCODE) &&
-       p->constants[n-F_MAX_OPCODE].sval.type==T_FUNCTION &&
-       (p->constants[n-F_MAX_OPCODE].sval.subtype == FUNCTION_BUILTIN) &&
-       p->constants[n-F_MAX_OPCODE].sval.u.efun)
-    {
-      return p->constants[n-F_MAX_OPCODE].sval.u.efun->name->str;
-    }else{
-      sprintf(buf, "Call efun %d", n - F_MAX_OPCODE);
-      return buf;
-    }
-  }else{
-    sprintf(buf, "<OTHER %d>", n);
-    return buf;
-  }
-}
-
-char *get_f_name(int n)
-{
-  static char buf[30];
-  if (n<F_MAX_OPCODE && instrs[n-F_OFFSET].name)
-  {
-    return instrs[n-F_OFFSET].name;
-  }else if(n >= F_MAX_OPCODE) {
-    if(Pike_fp && Pike_fp->context.prog &&
-       (int)Pike_fp->context.prog->num_constants > (int)(n-F_MAX_OPCODE) &&
-       Pike_fp->context.prog->constants[n-F_MAX_OPCODE].sval.type==T_FUNCTION &&
-       Pike_fp->context.prog->constants[n-F_MAX_OPCODE].sval.subtype == FUNCTION_BUILTIN &&
-       Pike_fp->context.prog->constants[n-F_MAX_OPCODE].sval.u.efun)
-    {
-      return Pike_fp->context.prog->constants[n-F_MAX_OPCODE].sval.u.efun->name->str;
-    }else{
-      sprintf(buf, "Call efun %d", n - F_MAX_OPCODE);
-      return buf;
-    }
-  }else{
-    sprintf(buf, "<OTHER %d>", n);
-    return buf;
-  }
-}
-
-#ifdef HAVE_COMPUTED_GOTO
-char *get_opcode_name(PIKE_INSTR_T n)
-{
-  int fcode;
-  int low = 0;
-  int high = F_MAX_OPCODE - F_OFFSET;
-  static char buf[64];
-
-  if (!n) {
-    return "<NULL opcode!>";
-  }
-
-  while (low < high) {
-    int mid = (low+high)/2;
-    if (opcode_to_fcode[mid].opcode < n) {
-      low = mid + 1;
-    } else if (opcode_to_fcode[mid].opcode > n) {
-      high = mid;
-    } else {
-      return get_f_name(opcode_to_fcode[mid].fcode);
-    }
-  }
-
-  sprintf(buf, "<Unknown opcode 0x%p>", n);
-  return buf;
-}
-#endif /* HAVE_COMPUTED_GOTO */
-
-char *get_token_name(int n)
-{
-  static char buf[30];
-  if (n<F_MAX_INSTR && instrs[n-F_OFFSET].name)
-  {
-    return instrs[n-F_OFFSET].name;
-  }else{
-    sprintf(buf, "<OTHER %d>", n);
-    return buf;
-  }
-}
-
 struct lex lex;
 
 /* Make lexers for shifts 0, 1 and 2. */
diff --git a/src/lex.h b/src/lex.h
index f35a39314d1b9fc61fca7aac91589de449e62431..d2b17584d1a3e5691d365201853ac0a69b94c3e7 100644
--- a/src/lex.h
+++ b/src/lex.h
@@ -2,125 +2,14 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: lex.h,v 1.30 2003/09/23 17:35:33 grubba Exp $
+|| $Id: lex.h,v 1.31 2003/11/14 10:12:29 mast Exp $
 */
 
 #ifndef LEX_H
 #define LEX_H
 
-#include <stdio.h>
-
 #include "program.h"
 
-struct keyword
-{
-  char *word;
-  int token;
-  int flags;
-#ifdef PIKE_USE_MACHINE_CODE
-  void *address;
-#endif
-};
-
-/*
- * Instruction flags
- *
- * Flags used to classify the instructions.
- *
- * Note that branches that take arguments use an immediately
- * following F_POINTER instruction to hold the destination
- * address.
- */
-#define I_HASARG	1	/* Instruction has a parameter. */
-#define I_POINTER	2	/* arg is a label number. */
-#define I_JUMP		4	/* Instruction performs a jump. */
-#define I__DATA		8	/* Instruction is raw data (data, byte)*/
-#define I_HASARG2	16	/* Instruction has a second parameter. */
-#define I_HASPOINTER	32	/* Instruction is followed by a F_POINTER. */
-#define I_PC_AT_NEXT	64	/* Opcode has updated Pike_fp->pc. */
-#define I_BRANCH	128	/* Opcode either jumps to the address
-				 * given by I_POINTER/I_HASPOINTER or
-				 * continues. */
-/* The following are useful for the code generator.
- * Note that they apply to the change of state as seen
- * by the immediately following instruction.
- */
-#define I_UPDATE_SP	256	/* Opcode modifies Pike_sp */
-#define I_UPDATE_FP	512	/* Opcode modifies Pike_fp */
-#define I_UPDATE_M_SP	1024	/* Opcode modifies Pike_mark_sp */
-
-/* Convenience variants */
-#define I_TWO_ARGS	(I_HASARG | I_HASARG2)
-#define I_DATA		(I_HASARG | I__DATA)
-#define I_ISPOINTER	(I_HASARG | I_POINTER)	/* Only F_POINTER */
-#define I_ISJUMP	(I_JUMP)
-#define I_ISJUMPARG	(I_HASARG | I_JUMP)
-#define I_ISJUMPARGS	(I_TWO_ARGS | I_JUMP)
-#define I_ISPTRJUMP	(I_HASARG | I_POINTER | I_JUMP)
-#define I_ISPTRJUMPARG	(I_HASARG | I_HASPOINTER | I_JUMP)
-#define I_ISPTRJUMPARGS	(I_TWO_ARGS | I_HASPOINTER | I_JUMP)
-#define I_ISBRANCH	(I_HASARG | I_POINTER | I_JUMP | I_BRANCH)
-#define I_ISBRANCHARG	(I_HASARG | I_HASPOINTER | I_JUMP | I_BRANCH)
-#define I_ISBRANCHARGS	(I_TWO_ARGS | I_HASPOINTER | I_JUMP | I_BRANCH)
-#define I_IS_MASK	(I_TWO_ARGS | I_POINTER | I_HASPOINTER | I_JUMP)
-
-#define I_UPDATE_ALL	(I_UPDATE_SP | I_UPDATE_FP | I_UPDATE_M_SP)
-
-/* Valid masked flags:
- *
- * 0			Generic instruction without immediate arguments.
- * I_HAS_ARG		Generic instruction with one argument.
- * I_TWO_ARGS		Generic instruction with two arguments.
- * I_DATA		Raw data (F_BYTE or F_DATA).
- * I_ISPOINTER		Raw jump address (F_POINTER).
- * I_ISJUMP		Jump instruction without immediate arguments.
- * I_ISJUMPARG		Jump instruction with one argument.
- * I_ISJUMPARGS		Jump instruction with two arguments.
- * I_ISPTRJUMP		Jump instruction with pointer.
- * I_ISPTRJUMPARG	Jump instruction with pointer and one argument.
- * I_ISPTRJUMPARGS	Jump instruction with pointer and two arguments.
- */
-
-#ifdef PIKE_DEBUG
-#define INSTR_PROFILING
-#endif
-
-
-struct instr
-{
-#ifdef PIKE_DEBUG
-  long compiles;
-#endif
-  int flags;
-  char *name;
-#ifdef PIKE_USE_MACHINE_CODE
-  void *address;
-#endif
-};
-
-#ifdef PIKE_DEBUG
-#define ADD_COMPILED(X) instrs[(X)-F_OFFSET].compiles++
-#ifdef INSTR_PROFILING
-extern void add_runned(PIKE_INSTR_T);
-#define ADD_RUNNED(X) add_runned(X)
-#else
-#define ADD_RUNNED(X)
-#endif
-#else
-#define ADD_COMPILED(X)
-#define ADD_RUNNED(X)
-#endif
-
-#ifndef STRUCT_HASH_ENTRY_DECLARED
-#define STRUCT_HASH_ENTRY_DECLARED
-struct hash_entry;
-#endif
-
-#ifndef STRUCT_HASH_TABLE_DECLARED
-#define STRUCT_HASH_TABLE_DECLARED
-struct hash_table;
-#endif
-
 #define NEW_LEX
 
 struct lex
@@ -134,20 +23,8 @@ struct lex
 };
 
 extern struct lex lex;
-extern struct instr instrs[];
 
 /* Prototypes begin here */
-void exit_lex(void);
-struct reserved;
-void init_lex(void);
-char *low_get_f_name(int n,struct program *p);
-char *get_f_name(int n);
-#ifdef HAVE_COMPUTED_GOTO
-char *get_opcode_name(PIKE_INSTR_T n);
-#else /* !HAVE_COMPUTED_GOTO */
-#define get_opcode_name(n) get_f_name(n + F_OFFSET)
-#endif /* HAVE_COMPUTED_GOTO */
-char *get_token_name(int n);
 
 int yylex0(YYSTYPE *);
 int yylex1(YYSTYPE *);
@@ -155,4 +32,4 @@ int yylex2(YYSTYPE *);
 
 /* Prototypes end here */
 
-#endif
+#endif	/* !LEX_H */
diff --git a/src/opcodes.c b/src/opcodes.c
index 0152bfc9ae310acc37abb75c4f9747ffe0809481..e26ab3967c0cb59932a0566099025ebe77e80792 100644
--- a/src/opcodes.c
+++ b/src/opcodes.c
@@ -2,9 +2,466 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: opcodes.c,v 1.156 2003/11/14 09:27:29 mast Exp $
+|| $Id: opcodes.c,v 1.157 2003/11/14 10:12:29 mast Exp $
 */
 
 #include "global.h"
+RCSID("$Id: opcodes.c,v 1.157 2003/11/14 10:12:29 mast Exp $");
+#include "constants.h"
+#include "interpret.h"
+#include "opcodes.h"
+#include "main.h"
 
-RCSID("$Id: opcodes.c,v 1.156 2003/11/14 09:27:29 mast Exp $");
+#ifdef INSTR_PROFILING
+
+/*
+ * If you have a 64 bit machine and 15+ Gb memory, this
+ * routine should handle -p4 nicely. -Hubbe
+ * (-p3 only requires ~38Mb on a 32bit machine)
+ */
+
+struct instr_counter
+{
+  long runned;
+  struct instr_counter* next[256];
+};
+
+int last_instruction[256];
+struct instr_counter *instr_counter_storage;
+
+struct instr_counter *init_instr_storage_pointers(int depth)
+{
+  int e;
+  struct instr_counter *d;
+  if(!depth) return 0;
+  d=ALLOC_STRUCT(instr_counter);
+  if(!d)
+  {
+    fprintf(stderr,"-p%d: out of memory.\n",p_flag);
+    exit(2);
+  }
+  dmalloc_accept_leak(d);
+  d->runned=0;
+  for(e=0;e<F_MAX_OPCODE-F_OFFSET;e++)
+    d->next[e]=init_instr_storage_pointers(depth-1);
+  return d;
+}
+
+void add_runned(PIKE_INSTR_T instr)
+{
+  int e;
+  struct instr_counter **tmp=&instr_counter_storage;
+
+  for(e=0;e<p_flag;e++)
+  {
+    tmp[0]->runned++;
+    tmp=tmp[0]->next + last_instruction[e];
+    last_instruction[e]=last_instruction[e+1];
+  }
+#ifndef HAVE_COMPUTED_GOTO
+  ((char **)(tmp))[0]++;
+#endif /* !HAVE_COMPUTED_GOTO */
+  last_instruction[e]=instr;
+}
+
+void present_runned(struct instr_counter *d, int depth, int maxdepth)
+{
+  int e;
+  if(depth == maxdepth)
+  {
+    long runned = depth < p_flag ? d->runned : (long)d;
+    if(!runned) return;
+    fprintf(stderr,"%010ld @%d@: ",runned,maxdepth);
+    for(e=0;e<depth;e++)
+    {
+      if(e) fprintf(stderr," :: ");
+      fprintf(stderr,"%s",
+	      low_get_f_name(last_instruction[e] + F_OFFSET,0));
+    }
+    fprintf(stderr,"\n");
+  }else{
+    for(e=0;e<F_MAX_OPCODE-F_OFFSET;e++)
+    {
+      last_instruction[depth]=e;
+      present_runned(d->next[e],depth+1, maxdepth);
+    }
+  }
+}
+
+#endif
+
+#ifdef PIKE_USE_MACHINE_CODE
+#define ADDR(X) , (void *)PIKE_CONCAT(opcode_,X)
+#define NULLADDR , 0
+#define ALIASADDR(X)	, (void *)(X)
+
+#define OPCODE0(OP,DESC,FLAGS) void PIKE_CONCAT(opcode_,OP)(void);
+#define OPCODE1(OP,DESC,FLAGS) void PIKE_CONCAT(opcode_,OP)(INT32);
+#define OPCODE2(OP,DESC,FLAGS) void PIKE_CONCAT(opcode_,OP)(INT32,INT32);
+
+#ifdef OPCODE_RETURN_JUMPADDR
+#define OPCODE0_JUMP(OP,DESC,FLAGS) void *PIKE_CONCAT(jump_opcode_,OP)(void);
+#define OPCODE1_JUMP(OP,DESC,FLAGS) void *PIKE_CONCAT(jump_opcode_,OP)(INT32);
+#define OPCODE2_JUMP(OP,DESC,FLAGS) void *PIKE_CONCAT(jump_opcode_,OP)(INT32,INT32);
+#define JUMPADDR(X) , (void *)PIKE_CONCAT(jump_opcode_,X)
+#else  /* !OPCODE_RETURN_JUMPADDR */
+#define OPCODE0_JUMP(OP, DESC, FLAGS) OPCODE0(OP, DESC, FLAGS)
+#define OPCODE1_JUMP(OP, DESC, FLAGS) OPCODE1(OP, DESC, FLAGS)
+#define OPCODE2_JUMP(OP, DESC, FLAGS) OPCODE2(OP, DESC, FLAGS)
+#define JUMPADDR(X) ADDR(X)
+#endif	/* !OPCODE_RETURN_JUMPADDR */
+
+#define OPCODE0_PTRJUMP(OP,DESC,FLAGS) OPCODE0_JUMP(OP, DESC, FLAGS)
+#define OPCODE1_PTRJUMP(OP,DESC,FLAGS) OPCODE1_JUMP(OP, DESC, FLAGS)
+#define OPCODE2_PTRJUMP(OP,DESC,FLAGS) OPCODE2_JUMP(OP, DESC, FLAGS)
+
+#define OPCODE0_RETURN(OP,DESC,FLAGS) OPCODE0_JUMP(OP, DESC, FLAGS)
+#define OPCODE1_RETURN(OP,DESC,FLAGS) OPCODE1_JUMP(OP, DESC, FLAGS)
+#define OPCODE2_RETURN(OP,DESC,FLAGS) OPCODE2_JUMP(OP, DESC, FLAGS)
+
+#define OPCODE0_ALIAS(OP, DESC, FLAGS, ADDR)
+#define OPCODE1_ALIAS(OP, DESC, FLAGS, ADDR)
+#define OPCODE2_ALIAS(OP, DESC, FLAGS, ADDR)
+
+#ifdef OPCODE_INLINE_BRANCH
+#define OPCODE0_BRANCH(OP,DESC,FLAGS) int PIKE_CONCAT(test_opcode_,OP)(void);
+#define OPCODE1_BRANCH(OP,DESC,FLAGS) int PIKE_CONCAT(test_opcode_,OP)(INT32);
+#define OPCODE2_BRANCH(OP,DESC,FLAGS) int PIKE_CONCAT(test_opcode_,OP)(INT32,INT32);
+#define BRANCHADDR(X) , (void *)PIKE_CONCAT(test_opcode_,X)
+#else /* !OPCODE_INLINE_BRANCH */
+#define OPCODE0_BRANCH		OPCODE0_PTRJUMP
+#define OPCODE1_BRANCH		OPCODE1_PTRJUMP
+#define OPCODE2_BRANCH		OPCODE2_PTRJUMP
+#define BRANCHADDR(X) JUMPADDR(X)
+#endif /* OPCODE_INLINE_BRANCH */
+
+#define OPCODE0_TAIL(OP,DESC,FLAGS) OPCODE0(OP,DESC,FLAGS)
+#define OPCODE1_TAIL(OP,DESC,FLAGS) OPCODE1(OP,DESC,FLAGS)
+#define OPCODE2_TAIL(OP,DESC,FLAGS) OPCODE2(OP,DESC,FLAGS)
+#define OPCODE0_TAILJUMP(OP,DESC,FLAGS) OPCODE0_JUMP(OP,DESC,FLAGS)
+#define OPCODE1_TAILJUMP(OP,DESC,FLAGS) OPCODE1_JUMP(OP,DESC,FLAGS)
+#define OPCODE2_TAILJUMP(OP,DESC,FLAGS) OPCODE2_JUMP(OP,DESC,FLAGS)
+#define OPCODE0_TAILPTRJUMP(OP,DESC,FLAGS) OPCODE0_PTRJUMP(OP, DESC, FLAGS)
+#define OPCODE1_TAILPTRJUMP(OP,DESC,FLAGS) OPCODE1_PTRJUMP(OP, DESC, FLAGS)
+#define OPCODE2_TAILPTRJUMP(OP,DESC,FLAGS) OPCODE2_PTRJUMP(OP, DESC, FLAGS)
+#define OPCODE0_TAILRETURN(OP,DESC,FLAGS) OPCODE0_RETURN(OP, DESC, FLAGS)
+#define OPCODE1_TAILRETURN(OP,DESC,FLAGS) OPCODE1_RETURN(OP, DESC, FLAGS)
+#define OPCODE2_TAILRETURN(OP,DESC,FLAGS) OPCODE2_RETURN(OP, DESC, FLAGS)
+#define OPCODE0_TAILBRANCH(OP,DESC,FLAGS) OPCODE0_BRANCH(OP,DESC,FLAGS)
+#define OPCODE1_TAILBRANCH(OP,DESC,FLAGS) OPCODE1_BRANCH(OP,DESC,FLAGS)
+#define OPCODE2_TAILBRANCH(OP,DESC,FLAGS) OPCODE2_BRANCH(OP,DESC,FLAGS)
+
+#include "interpret_protos.h"
+
+#undef OPCODE0
+#undef OPCODE1
+#undef OPCODE2
+#undef OPCODE0_TAIL
+#undef OPCODE1_TAIL
+#undef OPCODE2_TAIL
+
+#undef OPCODE0_JUMP
+#undef OPCODE1_JUMP
+#undef OPCODE2_JUMP
+#undef OPCODE0_TAILJUMP
+#undef OPCODE1_TAILJUMP
+#undef OPCODE2_TAILJUMP
+
+#undef OPCODE0_PTRJUMP
+#undef OPCODE1_PTRJUMP
+#undef OPCODE2_PTRJUMP
+#undef OPCODE0_TAILPTRJUMP
+#undef OPCODE1_TAILPTRJUMP
+#undef OPCODE2_TAILPTRJUMP
+
+#undef OPCODE0_RETURN
+#undef OPCODE1_RETURN
+#undef OPCODE2_RETURN
+#undef OPCODE0_TAILRETURN
+#undef OPCODE1_TAILRETURN
+#undef OPCODE2_TAILRETURN
+
+#undef OPCODE0_ALIAS
+#undef OPCODE1_ALIAS
+#undef OPCODE2_ALIAS
+
+#undef OPCODE0_BRANCH
+#undef OPCODE1_BRANCH
+#undef OPCODE2_BRANCH
+#undef OPCODE0_TAILBRANCH
+#undef OPCODE1_TAILBRANCH
+#undef OPCODE2_TAILBRANCH
+
+#else
+#define ADDR(X)
+#define BRANCHADDR(X)
+#define JUMPADDR(X)
+#define NULLADDR
+#define ALIASADDR(X)
+#endif
+
+#define OPCODE0(OP,DESC,FLAGS) { DESC, OP, FLAGS ADDR(OP) },
+#define OPCODE1(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_HASARG ADDR(OP) },
+#define OPCODE2(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_TWO_ARGS ADDR(OP) },
+#define OPCODE0_TAIL(OP,DESC,FLAGS) OPCODE0(OP,DESC,FLAGS)
+#define OPCODE1_TAIL(OP,DESC,FLAGS) OPCODE1(OP,DESC,FLAGS)
+#define OPCODE2_TAIL(OP,DESC,FLAGS) OPCODE2(OP,DESC,FLAGS)
+
+#define OPCODE0_PTRJUMP(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISPTRJUMP JUMPADDR(OP) },
+#define OPCODE1_PTRJUMP(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISPTRJUMPARG JUMPADDR(OP) },
+#define OPCODE2_PTRJUMP(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISPTRJUMPARGS JUMPADDR(OP) },
+#define OPCODE0_TAILPTRJUMP(OP,DESC,FLAGS) OPCODE0_PTRJUMP(OP,DESC,FLAGS)
+#define OPCODE1_TAILPTRJUMP(OP,DESC,FLAGS) OPCODE1_PTRJUMP(OP,DESC,FLAGS)
+#define OPCODE2_TAILPTRJUMP(OP,DESC,FLAGS) OPCODE2_PTRJUMP(OP,DESC,FLAGS)
+
+#define OPCODE0_JUMP(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISJUMP JUMPADDR(OP) },
+#define OPCODE1_JUMP(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISJUMPARG JUMPADDR(OP) },
+#define OPCODE2_JUMP(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISJUMPARGS JUMPADDR(OP) },
+#define OPCODE0_TAILJUMP(OP, DESC, FLAGS) OPCODE0_JUMP(OP,DESC,FLAGS)
+#define OPCODE1_TAILJUMP(OP, DESC, FLAGS) OPCODE1_JUMP(OP,DESC,FLAGS)
+#define OPCODE2_TAILJUMP(OP, DESC, FLAGS) OPCODE2_JUMP(OP,DESC,FLAGS)
+
+#define OPCODE0_RETURN(OP, DESC, FLAGS) OPCODE0_JUMP(OP,DESC,FLAGS)
+#define OPCODE1_RETURN(OP, DESC, FLAGS) OPCODE1_JUMP(OP,DESC,FLAGS)
+#define OPCODE2_RETURN(OP, DESC, FLAGS) OPCODE2_JUMP(OP,DESC,FLAGS)
+#define OPCODE0_TAILRETURN(OP, DESC, FLAGS) OPCODE0_RETURN(OP,DESC,FLAGS)
+#define OPCODE1_TAILRETURN(OP, DESC, FLAGS) OPCODE1_RETURN(OP,DESC,FLAGS)
+#define OPCODE2_TAILRETURN(OP, DESC, FLAGS) OPCODE2_RETURN(OP,DESC,FLAGS)
+
+#define OPCODE0_ALIAS(OP, DESC, FLAGS, A) { DESC, OP, FLAGS ALIASADDR(A) },
+#define OPCODE1_ALIAS(OP, DESC, FLAGS, A) { DESC, OP, FLAGS | I_HASARG ALIASADDR(A) },
+#define OPCODE2_ALIAS(OP, DESC, FLAGS, A) { DESC, OP, FLAGS | I_TWO_ARGS ALIASADDR(A) },
+
+#define OPCODE0_BRANCH(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISBRANCH BRANCHADDR(OP) },
+#define OPCODE1_BRANCH(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISBRANCHARG BRANCHADDR(OP) },
+#define OPCODE2_BRANCH(OP,DESC,FLAGS) { DESC, OP, FLAGS | I_ISBRANCHARGS BRANCHADDR(OP) },
+#define OPCODE0_TAILBRANCH(OP,DESC,FLAGS) OPCODE0_BRANCH(OP,DESC,FLAGS)
+#define OPCODE1_TAILBRANCH(OP,DESC,FLAGS) OPCODE1_BRANCH(OP,DESC,FLAGS)
+#define OPCODE2_TAILBRANCH(OP,DESC,FLAGS) OPCODE2_BRANCH(OP,DESC,FLAGS)
+
+#define LEXER
+
+struct keyword instr_names[]=
+{
+#ifndef PIKE_PRECOMPILER
+#include "interpret_protos.h"
+#endif /* !PIKE_PRECOMPILER */
+{ "%=",			F_MOD_EQ,0 NULLADDR },	
+{ "&=",			F_AND_EQ,0 NULLADDR },	
+{ "|=",			F_OR_EQ,0 NULLADDR },	
+{ "*=",			F_MULT_EQ,0 NULLADDR },	
+{ "+=",			F_ADD_EQ,0 NULLADDR },	
+{ "-=",			F_SUB_EQ,0 NULLADDR },	
+{ "/=",			F_DIV_EQ,0 NULLADDR },	
+{ "<<=",		F_LSH_EQ,0 NULLADDR },	
+{ ">>=",		F_RSH_EQ,0 NULLADDR },	
+{ "^=",			F_XOR_EQ,0 NULLADDR },	
+{ "arg+=1024",		F_PREFIX_1024,0 NULLADDR },
+{ "arg+=256",		F_PREFIX_256,0 NULLADDR },
+{ "arg+=256*X",		F_PREFIX_CHARX256,0 NULLADDR },
+{ "arg+=256*XX",	F_PREFIX_WORDX256,0 NULLADDR },
+{ "arg+=256*XXX",	F_PREFIX_24BITX256,0 NULLADDR },
+{ "arg+=512",		F_PREFIX_512,0 NULLADDR },
+{ "arg+=768",		F_PREFIX_768,0 NULLADDR },
+
+{ "arg+=1024",		F_PREFIX2_1024,0 NULLADDR },
+{ "arg+=256",		F_PREFIX2_256,0 NULLADDR },
+{ "arg+=256*X",		F_PREFIX2_CHARX256,0 NULLADDR },
+{ "arg+=256*XX",	F_PREFIX2_WORDX256,0 NULLADDR },
+{ "arg+=256*XXX",	F_PREFIX2_24BITX256,0 NULLADDR },
+{ "arg+=512",		F_PREFIX2_512,0 NULLADDR },
+{ "arg+=768",		F_PREFIX2_768,0 NULLADDR },
+
+{ "break",		F_BREAK,0 NULLADDR },	
+{ "case",		F_CASE,0 NULLADDR },	
+{ "continue",		F_CONTINUE,0 NULLADDR },	
+{ "default",		F_DEFAULT,0 NULLADDR },	
+{ "do-while",		F_DO,0 NULLADDR },	
+{ "for",		F_FOR,0 NULLADDR },
+
+{ "pointer",		F_POINTER, I_ISPOINTER NULLADDR },
+{ "data",		F_DATA, I_DATA NULLADDR },
+{ "byte",		F_BYTE, I_DATA NULLADDR },
+{ "lvalue_list",	F_LVALUE_LIST,0 NULLADDR },	
+{ "label",		F_LABEL,I_HASARG NULLADDR },
+{ "align",		F_ALIGN, I_HASARG NULLADDR },
+{ "nop",                F_NOP,0 NULLADDR },
+{ "entry",		F_ENTRY,0 NULLADDR },
+{ "function start",     F_START_FUNCTION,0 NULLADDR },
+{ "notreached!",        F_NOTREACHED, 0 NULLADDR },
+};
+
+struct instr instrs[F_MAX_INSTR - F_OFFSET];
+
+char *low_get_f_name(int n,struct program *p)
+{
+  static char buf[30];
+  
+  if (n<F_MAX_OPCODE && instrs[n-F_OFFSET].name)
+  {
+    return instrs[n-F_OFFSET].name;
+  }else if(n >= F_MAX_OPCODE) {
+    if(p &&
+       (int)p->num_constants > (int)(n-F_MAX_OPCODE) &&
+       p->constants[n-F_MAX_OPCODE].sval.type==T_FUNCTION &&
+       (p->constants[n-F_MAX_OPCODE].sval.subtype == FUNCTION_BUILTIN) &&
+       p->constants[n-F_MAX_OPCODE].sval.u.efun)
+    {
+      return p->constants[n-F_MAX_OPCODE].sval.u.efun->name->str;
+    }else{
+      sprintf(buf, "Call efun %d", n - F_MAX_OPCODE);
+      return buf;
+    }
+  }else{
+    sprintf(buf, "<OTHER %d>", n);
+    return buf;
+  }
+}
+
+char *get_f_name(int n)
+{
+  static char buf[30];
+  if (n<F_MAX_OPCODE && instrs[n-F_OFFSET].name)
+  {
+    return instrs[n-F_OFFSET].name;
+  }else if(n >= F_MAX_OPCODE) {
+    if(Pike_fp && Pike_fp->context.prog &&
+       (int)Pike_fp->context.prog->num_constants > (int)(n-F_MAX_OPCODE) &&
+       Pike_fp->context.prog->constants[n-F_MAX_OPCODE].sval.type==T_FUNCTION &&
+       Pike_fp->context.prog->constants[n-F_MAX_OPCODE].sval.subtype == FUNCTION_BUILTIN &&
+       Pike_fp->context.prog->constants[n-F_MAX_OPCODE].sval.u.efun)
+    {
+      return Pike_fp->
+	context.prog->
+	constants[n-F_MAX_OPCODE]
+	.sval
+	.u
+	.efun->
+	name->
+	str;
+    }else{
+      sprintf(buf, "Call efun %d", n - F_MAX_OPCODE);
+      return buf;
+    }
+  }else{
+    sprintf(buf, "<OTHER %d>", n);
+    return buf;
+  }
+}
+
+#ifdef HAVE_COMPUTED_GOTO
+char *get_opcode_name(PIKE_INSTR_T n)
+{
+  int fcode;
+  int low = 0;
+  int high = F_MAX_OPCODE - F_OFFSET;
+  static char buf[64];
+
+  if (!n) {
+    return "<NULL opcode!>";
+  }
+
+  while (low < high) {
+    int mid = (low+high)/2;
+    if (opcode_to_fcode[mid].opcode < n) {
+      low = mid + 1;
+    } else if (opcode_to_fcode[mid].opcode > n) {
+      high = mid;
+    } else {
+      return get_f_name(opcode_to_fcode[mid].fcode);
+    }
+  }
+
+  sprintf(buf, "<Unknown opcode 0x%p>", n);
+  return buf;
+}
+#endif /* HAVE_COMPUTED_GOTO */
+
+char *get_token_name(int n)
+{
+  static char buf[30];
+  if (n<F_MAX_INSTR && instrs[n-F_OFFSET].name)
+  {
+    return instrs[n-F_OFFSET].name;
+  }else{
+    sprintf(buf, "<OTHER %d>", n);
+    return buf;
+  }
+}
+
+void init_opcodes(void)
+{
+  unsigned int i;
+#ifdef PIKE_DEBUG
+  int fatal_later=0;
+#ifdef INSTR_PROFILING
+  instr_counter_storage=init_instr_storage_pointers(p_flag);
+#endif
+#endif
+
+  for(i=0; i<NELEM(instr_names);i++)
+  {
+#ifdef PIKE_DEBUG
+    if(instr_names[i].token >= F_MAX_INSTR)
+    {
+      fprintf(stderr,"Error in instr_names[%u]\n\n",i);
+      fatal_later++;
+    }
+
+    if(instrs[instr_names[i].token - F_OFFSET].name)
+    {
+      fprintf(stderr,"Duplicate name for %s\n",instr_names[i].word);
+      fatal_later++;
+    }
+#endif
+
+    instrs[instr_names[i].token - F_OFFSET].name = instr_names[i].word;
+    instrs[instr_names[i].token - F_OFFSET].flags=instr_names[i].flags;
+#ifdef PIKE_USE_MACHINE_CODE
+    instrs[instr_names[i].token - F_OFFSET].address=instr_names[i].address;
+#endif
+  }
+
+#ifdef PIKE_DEBUG
+  for(i=1; i<F_MAX_OPCODE-F_OFFSET;i++)
+  {
+    if(!instrs[i].name)
+    {
+      fprintf(stderr,"Opcode %d does not have a name.\n",i);
+      fatal_later++;
+    }
+  }
+  if(fatal_later)
+    Pike_fatal("Found %d errors in instrs.\n",fatal_later);
+
+#endif
+
+}
+
+void exit_opcodes(void)
+{
+#ifdef PIKE_DEBUG
+  if(p_flag)
+  {
+    extern void present_constant_profiling(void);
+    int e;
+    present_constant_profiling();
+
+    fprintf(stderr,"Opcode compiles: (opcode, compiled)\n");
+    for(e=0;e<F_MAX_OPCODE-F_OFFSET;e++)
+    {
+      fprintf(stderr,"%08ld;;%-30s\n",
+	      (long)instrs[e].compiles,
+	      low_get_f_name(e+F_OFFSET,0));
+    }
+
+#ifdef INSTR_PROFILING
+    for(e=0;e<=p_flag;e++)
+    {
+      fprintf(stderr,"Opcode x %d usage:\n",e);
+      present_runned(instr_counter_storage, 0, e);
+    }
+  }
+#endif
+#endif
+}
diff --git a/src/opcodes.h b/src/opcodes.h
index 4d3a2d8487ca8c554750bfaa1b8c44bce6ac2677..e5bea8a2d0fb84227d7adcc7367bf12e51ce56ae 100644
--- a/src/opcodes.h
+++ b/src/opcodes.h
@@ -2,17 +2,130 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: opcodes.h,v 1.35 2003/11/14 09:27:29 mast Exp $
+|| $Id: opcodes.h,v 1.36 2003/11/14 10:12:29 mast Exp $
 */
 
 #ifndef OPCODES_H
 #define OPCODES_H
 
+#include "pikecode.h"
+
 /* To provide the cast and sscanf declarations for compatibility. */
 #include "operators.h"
 #include "sscanf.h"
 
-/* Opcodes */
+struct keyword
+{
+  char *word;
+  int token;
+  int flags;
+#ifdef PIKE_USE_MACHINE_CODE
+  void *address;
+#endif
+};
+
+/*
+ * Instruction flags
+ *
+ * Flags used to classify the instructions.
+ *
+ * Note that branches that take arguments use an immediately
+ * following F_POINTER instruction to hold the destination
+ * address.
+ */
+#define I_HASARG	1	/* Instruction has a parameter. */
+#define I_POINTER	2	/* arg is a label number. */
+#define I_JUMP		4	/* Instruction performs a jump. */
+#define I__DATA		8	/* Instruction is raw data (data, byte)*/
+#define I_HASARG2	16	/* Instruction has a second parameter. */
+#define I_HASPOINTER	32	/* Instruction is followed by a F_POINTER. */
+#define I_PC_AT_NEXT	64	/* Opcode has updated Pike_fp->pc. */
+#define I_BRANCH	128	/* Opcode either jumps to the address
+				 * given by I_POINTER/I_HASPOINTER or
+				 * continues. */
+/* The following are useful for the code generator.
+ * Note that they apply to the change of state as seen
+ * by the immediately following instruction.
+ */
+#define I_UPDATE_SP	256	/* Opcode modifies Pike_sp */
+#define I_UPDATE_FP	512	/* Opcode modifies Pike_fp */
+#define I_UPDATE_M_SP	1024	/* Opcode modifies Pike_mark_sp */
+
+/* Convenience variants */
+#define I_TWO_ARGS	(I_HASARG | I_HASARG2)
+#define I_DATA		(I_HASARG | I__DATA)
+#define I_ISPOINTER	(I_HASARG | I_POINTER)	/* Only F_POINTER */
+#define I_ISJUMP	(I_JUMP)
+#define I_ISJUMPARG	(I_HASARG | I_JUMP)
+#define I_ISJUMPARGS	(I_TWO_ARGS | I_JUMP)
+#define I_ISPTRJUMP	(I_HASARG | I_POINTER | I_JUMP)
+#define I_ISPTRJUMPARG	(I_HASARG | I_HASPOINTER | I_JUMP)
+#define I_ISPTRJUMPARGS	(I_TWO_ARGS | I_HASPOINTER | I_JUMP)
+#define I_ISBRANCH	(I_HASARG | I_POINTER | I_JUMP | I_BRANCH)
+#define I_ISBRANCHARG	(I_HASARG | I_HASPOINTER | I_JUMP | I_BRANCH)
+#define I_ISBRANCHARGS	(I_TWO_ARGS | I_HASPOINTER | I_JUMP | I_BRANCH)
+#define I_IS_MASK	(I_TWO_ARGS | I_POINTER | I_HASPOINTER | I_JUMP)
+
+#define I_UPDATE_ALL	(I_UPDATE_SP | I_UPDATE_FP | I_UPDATE_M_SP)
+
+/* Valid masked flags:
+ *
+ * 0			Generic instruction without immediate arguments.
+ * I_HAS_ARG		Generic instruction with one argument.
+ * I_TWO_ARGS		Generic instruction with two arguments.
+ * I_DATA		Raw data (F_BYTE or F_DATA).
+ * I_ISPOINTER		Raw jump address (F_POINTER).
+ * I_ISJUMP		Jump instruction without immediate arguments.
+ * I_ISJUMPARG		Jump instruction with one argument.
+ * I_ISJUMPARGS		Jump instruction with two arguments.
+ * I_ISPTRJUMP		Jump instruction with pointer.
+ * I_ISPTRJUMPARG	Jump instruction with pointer and one argument.
+ * I_ISPTRJUMPARGS	Jump instruction with pointer and two arguments.
+ */
+
+#ifdef PIKE_DEBUG
+#define INSTR_PROFILING
+#endif
+
+
+struct instr
+{
+#ifdef PIKE_DEBUG
+  long compiles;
+#endif
+  int flags;
+  char *name;
+#ifdef PIKE_USE_MACHINE_CODE
+  void *address;
+#endif
+};
+
+#ifdef PIKE_DEBUG
+#define ADD_COMPILED(X) instrs[(X)-F_OFFSET].compiles++
+#ifdef INSTR_PROFILING
+extern void add_runned(PIKE_INSTR_T);
+#define ADD_RUNNED(X) add_runned(X)
+#else
+#define ADD_RUNNED(X)
+#endif
+#else
+#define ADD_COMPILED(X)
+#define ADD_RUNNED(X)
+#endif
+
+#ifndef STRUCT_HASH_ENTRY_DECLARED
+#define STRUCT_HASH_ENTRY_DECLARED
+struct hash_entry;
+#endif
+
+#ifndef STRUCT_HASH_TABLE_DECLARED
+#define STRUCT_HASH_TABLE_DECLARED
+struct hash_table;
+#endif
+
+extern struct instr instrs[];
+
+/* Opcode enum */
 
 #define OPCODE0(X,Y,F) X,
 #define OPCODE1(X,Y,F) X,
@@ -162,4 +275,15 @@ enum Pike_opcodes
 #undef OPCODE1_ALIAS
 #undef OPCODE2_ALIAS
 
-#endif
+char *low_get_f_name(int n,struct program *p);
+char *get_f_name(int n);
+#ifdef HAVE_COMPUTED_GOTO
+char *get_opcode_name(PIKE_INSTR_T n);
+#else /* !HAVE_COMPUTED_GOTO */
+#define get_opcode_name(n) get_f_name(n + F_OFFSET)
+#endif /* HAVE_COMPUTED_GOTO */
+char *get_token_name(int n);
+void init_opcodes(void);
+void exit_opcodes(void);
+
+#endif	/* !OPCODES_H */