From a96ce9ba992f5602e54d0ce60fed821697ab775d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Wed, 19 Apr 2000 19:41:45 -0700
Subject: [PATCH] bye bye accumulator

Rev: bin/mkpeep.pike:1.14
Rev: src/Makefile.in:1.190
Rev: src/array.c:1.67
Rev: src/docode.c:1.68
Rev: src/docode.h:1.9
Rev: src/error.h:1.41
Rev: src/gc.c:1.75
Rev: src/interpret_functions.h:1.10
Rev: src/interpreter.h:1.42
Rev: src/language.yacc:1.180
Rev: src/lex.c:1.74
Rev: src/lex.h:1.15
Rev: src/object.c:1.117
Rev: src/opcodes.c:1.74
Rev: src/operators.c:1.91
Rev: src/peep.c:1.30
Rev: src/peep.h:1.5
Rev: src/peep.in:1.28
---
 bin/mkpeep.pike           | 105 ++++++++++++++++---
 src/Makefile.in           |   8 +-
 src/array.c               |  14 +--
 src/docode.c              | 210 +++++++++++++++++++-------------------
 src/docode.h              |   7 +-
 src/error.h               |   4 +-
 src/gc.c                  |  11 +-
 src/interpret_functions.h | 177 +++++++++++++++++---------------
 src/interpreter.h         |  29 ++++--
 src/language.yacc         |  10 +-
 src/lex.c                 |  56 +++++++---
 src/lex.h                 |   4 +-
 src/object.c              |  10 +-
 src/opcodes.c             |   5 +-
 src/operators.c           |  46 ++++-----
 src/peep.c                | 186 +++++++++++++++++++++++++++------
 src/peep.h                |  14 ++-
 src/peep.in               |  28 ++---
 18 files changed, 589 insertions(+), 335 deletions(-)

diff --git a/bin/mkpeep.pike b/bin/mkpeep.pike
index 998f9c352d..898732a934 100755
--- a/bin/mkpeep.pike
+++ b/bin/mkpeep.pike
@@ -2,7 +2,7 @@
 
 #pragma strict_types
 
-/* $Id: mkpeep.pike,v 1.13 2000/01/05 13:57:39 jonasw Exp $ */
+/* $Id: mkpeep.pike,v 1.14 2000/04/20 02:41:27 hubbe Exp $ */
 
 #define JUMPBACK 3
 
@@ -16,6 +16,14 @@ string skipwhite(string s)
   return s;
 }
 
+string stripwhite(string s)
+{
+  sscanf(s,"%*[ \t\n]%s",s);
+  s=reverse(s);
+  sscanf(s,"%*[ \t\n]%s",s);
+  return reverse(s);
+}
+
 /* Find the matching parenthesis */
 int find_end(string s)
 {
@@ -35,12 +43,54 @@ int find_end(string s)
       parlvl--;
       if(!parlvl) return e;
       break;
+    case '"':
+      while(s[e]!='"') e+=1+(s[e]=='\\');
+      break;
     }
   }
   werror("Syntax error (1).\n");
   exit(1);
 }
 
+array(string) explode_comma_expr(string s)
+{
+#if DEBUG>4
+  werror("Exploding %O\n",s);
+#endif
+  int parlvl;
+  array(string) ret=({});
+  int begin=0;
+
+  for(int e=0;e<strlen(s);e++)
+  {
+    switch(s[e])
+    {
+    case '(': case '{': case '[':
+      parlvl++; break;
+    case ')': case '}': case ']':
+      parlvl--; break;
+    case '"':
+      while(s[e]!='"') e+=1+(s[e]=='\\');
+      break;
+
+    case ',':
+      if(!parlvl)
+      {
+	ret+=({ stripwhite(s[begin..e-1]) });
+	begin=e+1;
+      }
+    }
+  }
+
+  /* Ignore empty last arguments */
+  if(strlen(stripwhite(s[begin..])))
+    ret+=({ stripwhite(s[begin..]) });
+#if DEBUG>4
+  werror("RESULT: %O\n",ret);
+#endif
+  return ret;
+}
+
 
 /* Splitline into components */
 array(int|string|array(string)) split(string s)
@@ -57,6 +107,8 @@ array(int|string|array(string)) split(string s)
   b=({});
 
   s=skipwhite(s);
+  
+  /* First, we tokenize */
   while(strlen(s))
   {
     switch(s[0])
@@ -99,6 +151,7 @@ array(int|string|array(string)) split(string s)
     s=skipwhite(s);
   }
 
+  /* Find the source/dest separator */
   int i=search(b, ":");
   if(i==-1)
   {
@@ -106,9 +159,11 @@ array(int|string|array(string)) split(string s)
     return 0;
   }
 
+  /* a=source, b=dest */
   a=b[..i-1];
   b=b[i+1..];
 
+  /* Count 'steps' in source */
   for(e=0;e<sizeof(a);e++)
     if(a[e][0]=='F')
       opcodes++;
@@ -138,26 +193,32 @@ array(int|string|array(string)) split(string s)
 #endif
 
   i=0;
+  array newa=({});
   for(e=0;e<sizeof(a);e++)
   {
     switch(a[e][0])
     {
-    case '(':
-      a[e]=a[e]+"==$"+i+"a";
+      case '(':
+	array tmp=explode_comma_expr(a[e][1..strlen(a[e])-2]);
+	for(int x=0;x<sizeof(tmp);x++)
+	  newa+=({ sprintf("(%s)==$%d%c",tmp[x], i, 'a'+x) });
       break;
 
     case '[':
-      a[e]=a[e][1..strlen(a[e])-2];
+      newa+=({ a[e][1..strlen(a[e])-2] });
       break;
 
     case 'F':
       i++;
-      a[e]=a[e]+"==$"+i+"o";
+      newa+=({ a[e]+"==$"+i+"o" });
       break;
+
+      default: newa+=({a[e]});
     }
   }
+  a=newa;
 
-
+  // Magic for the '!' operator
   for(e=0;e<sizeof(a);e++)
   {
     if(a[e]=="!")
@@ -172,7 +233,7 @@ array(int|string|array(string)) split(string s)
   return ({a,b,opcodes, line,a});
 }
 
-/* Replace $[0-9]+(o|a) with something a C compiler can understand */
+/* Replace $[0-9]+(o|a|b) with something a C compiler can understand */
 string treat(string expr)
 {
   int e;
@@ -191,6 +252,7 @@ string treat(string expr)
     switch(type)
     {
     case 'a': tmp[e]="argument("+num+")"+rest; break;
+    case 'b': tmp[e]="argument2("+num+")"+rest; break;
     case 'o': tmp[e]="opcode("+num+")"+rest; break;
     }
   }
@@ -306,14 +368,20 @@ void dump2(array(mixed) data,int ind)
 
       for(i=0;i<sizeof(d[1]);i++)
       {
+	array args=({});
+	string fcode=d[1][i];
 	if(i+1<sizeof(d[1]) && d[1][i+1][0]=='(')
 	{
 	  string tmp=d[1][i+1];
-	  write("%*n                2,%s,%s,\n",ind,d[1][i],treat(tmp[1..strlen(tmp)-2]));
+	  args=explode_comma_expr(tmp[1..strlen(tmp)-2]);
 	  i++;
-	}else{
-	  write("%*n                1,%s,\n",ind,d[1][i]);
 	}
+	write("%*n                %d,%s,%{(%s), %}\n",
+	      ind,
+	      sizeof(args)+1,
+	      fcode,
+	      Array.map(args,treat));
+
       }
       write("%*n                0);\n",ind);
 
@@ -335,6 +403,7 @@ int main(int argc, string *argv)
 
   mapping tests=([]);
 
+  /* Read input file */
   f=cpp(Stdio.read_bytes(argv[1]),argv[1]);
   foreach(f/"\n",f)
   {
@@ -342,6 +411,8 @@ int main(int argc, string *argv)
     mapping tmp;
 
     sscanf(f,"%s#",f);
+
+    /* Parse expressions */
     foreach(f/";",f)
       {
 	f=skipwhite(f);
@@ -361,13 +432,15 @@ int main(int argc, string *argv)
   write("    INT32 current_line;\n");
   write("    struct pike_string *current_file;\n");
   write("\n");
-  write("#ifdef DEBUG\n");
-  write("    if(a_flag>5) {\n");
+  write("#ifdef PIKE_DEBUG\n");
+  write("    if(a_flag>6) {\n");
+  write("      int e;\n");
   write("      fprintf(stderr,\"#%d,%d:\",eye,fifo_len);\n");
-  write("      fprintf(stderr,\" %s(%d)\",  get_token_name(opcode(0)),argument(0));\n");
-  write("      fprintf(stderr,\" %s(%d)\",  get_token_name(opcode(1)),argument(1));\n");
-  write("      fprintf(stderr,\" %s(%d)\",  get_token_name(opcode(2)),argument(2));\n");
-  write("      fprintf(stderr,\" %s(%d)\\n\",get_token_name(opcode(3)),argument(3));\n");
+  write("      for(e=0;e<4;e++) {\n");
+  write("        fprintf(stderr,\" \");\n");
+  write("        dump_instr(instr(e));\n");
+  write("      }\n");
+  write("      fprintf(stderr,\"\n\");\n");
   write("    }\n");
   write("#endif\n\n");
 
diff --git a/src/Makefile.in b/src/Makefile.in
index 4441b98bd9..836eef221a 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile.in,v 1.189 2000/04/18 19:08:28 grubba Exp $
+# $Id: Makefile.in,v 1.190 2000/04/20 02:41:44 hubbe Exp $
 #
 
 # This line is needed on some machines.
@@ -456,21 +456,21 @@ new_peep_engine:
 	$(RUNPIKE) $(TMP_BINDIR)/make_ci.pike <$(SRCDIR)/UnicodeData.txt >$(SRCDIR)/case_info.h
 
 $(SRCDIR)/peep_engine.c: $(TMP_BUILDDIR)/tpike $(SRCDIR)/peep.in $(TMP_BINDIR)/mkpeep.pike
-	$(RUNTPIKE) $(TMP_BINDIR)/mkpeep.pike $(SRCDIR)/peep.in >$(SRCDIR)/peep_engine.c
+	$(RUNTPIKE) $(TMP_BINDIR)/mkpeep.pike $(SRCDIR)/peep.in >$(SRCDIR)/peep_engine.c || ( mv $(TMP_BUILDDIR)/tpike  $(TMP_BUILDDIR)/tpike.bug ; exit 1 )
 
 peep.o: $(SRCDIR)/peep_engine.c
 
 peep_t.o: peep.c
 
 $(SRCDIR)/case_info.h: $(TMP_BUILDDIR)/tpike $(SRCDIR)/UnicodeData.txt $(TMP_BINDIR)/make_ci.pike
-	$(RUNTPIKE) $(TMP_BINDIR)/make_ci.pike <$(SRCDIR)/UnicodeData.txt >$(SRCDIR)/case_info.h
+	$(RUNTPIKE) $(TMP_BINDIR)/make_ci.pike <$(SRCDIR)/UnicodeData.txt >$(SRCDIR)/case_info.h || ( mv $(TMP_BUILDDIR)/tpike  $(TMP_BUILDDIR)/tpike.bug ; exit 1 )
 
 builtin_functions.o: $(SRCDIR)/case_info.h
 
 builtin_functions_t.o: builtin_functions.c
 
 $(SRCDIR)/treeopt.h: $(TMP_BUILDDIR)/tpike $(SRCDIR)/treeopt.in $(TMP_BINDIR)/mktreeopt.pike
-	$(RUNTPIKE) $(TMP_BINDIR)/mktreeopt.pike $(SRCDIR)/treeopt.in
+	$(RUNTPIKE) $(TMP_BINDIR)/mktreeopt.pike $(SRCDIR)/treeopt.in || ( mv $(TMP_BUILDDIR)/tpike  $(TMP_BUILDDIR)/tpike.bug ; exit 1 )
 
 las.o: $(SRCDIR)/treeopt.h
 
diff --git a/src/array.c b/src/array.c
index 663e52a27e..151cba7a35 100644
--- a/src/array.c
+++ b/src/array.c
@@ -23,7 +23,7 @@
 #include "stuff.h"
 #include "bignum.h"
 
-RCSID("$Id: array.c,v 1.66 2000/04/20 01:49:42 mast Exp $");
+RCSID("$Id: array.c,v 1.67 2000/04/20 02:41:44 hubbe Exp $");
 
 struct array empty_array=
 {
@@ -1966,16 +1966,8 @@ void zap_all_arrays(void)
     
     if(!(next=a->next))
       fatal("Null pointer in array list.\n");
-    
-    while((next=a->next) != &empty_array && a->refs == 1)
-    {
-      add_ref(next);
-      free_program(a);
-      a=next;
-    }
-    
-    free_array(a);
-    a=next;
+
+    SET_NEXT_AND_FREE(a,free_array);
   } while (a != & empty_array);
 }
 
diff --git a/src/docode.c b/src/docode.c
index df7492e529..62343a50fd 100644
--- a/src/docode.c
+++ b/src/docode.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: docode.c,v 1.67 2000/03/30 08:43:07 hubbe Exp $");
+RCSID("$Id: docode.c,v 1.68 2000/04/20 02:41:44 hubbe Exp $");
 #include "las.h"
 #include "program.h"
 #include "language.h"
@@ -55,7 +55,7 @@ int alloc_label(void) { return ++label_no; }
 int do_jump(int token,INT32 lbl)
 {
   if(lbl==-1) lbl=alloc_label();
-  emit(token, lbl);
+  emit1(token, lbl);
   return lbl;
 }
 
@@ -66,8 +66,8 @@ void do_pop(int x)
   switch(x)
   {
   case 0: return;
-  case 1: emit2(F_POP_VALUE); break;
-  default: emit(F_POP_N_ELEMS,x); break;
+  case 1: emit0(F_POP_VALUE); break;
+  default: emit1(F_POP_N_ELEMS,x); break;
   }
 }
 
@@ -130,7 +130,7 @@ void do_cond_jump(node *n, int label, int iftrue, int flags)
       int tmp=alloc_label();
       do_cond_jump(CAR(n), tmp, !iftrue, flags | DO_POP);
       do_cond_jump(CDR(n), label, iftrue, flags);
-      emit(F_LABEL,tmp);
+      emit1(F_LABEL,tmp);
     }else{
       do_cond_jump(CAR(n), label, iftrue, flags);
       do_cond_jump(CDR(n), label, iftrue, flags);
@@ -212,8 +212,8 @@ static int do_docode2(node *n,int flags)
     {
       default:
 	yyerror("Illegal lvalue.");
-	emit(F_NUMBER,0);
-	emit(F_NUMBER,0);
+	emit1(F_NUMBER,0);
+	emit1(F_NUMBER,0);
 	return 2;
 	
       case F_ARRAY_LVALUE:
@@ -246,10 +246,10 @@ static int do_docode2(node *n,int flags)
     {
       yyerror("Too deep recursion in compiler. (please report this)");
 
-      emit(F_NUMBER,0);
+      emit1(F_NUMBER,0);
       if(flags & DO_LVALUE)
       {
-	emit(F_NUMBER,0);
+	emit1(F_NUMBER,0);
 	return 2;
       }
       return 1;
@@ -260,30 +260,30 @@ static int do_docode2(node *n,int flags)
   {
   case F_MAGIC_INDEX:
   case F_MAGIC_SET_INDEX:
-    emit(F_LDA, n->u.node.a->u.sval.u.integer);
-    emit(n->token, n->u.node.b->u.sval.u.integer);
+    emit2(n->token,
+	  n->u.node.b->u.sval.u.integer,
+	  n->u.node.a->u.sval.u.integer);
     return 1;
       
   case F_EXTERNAL:
-    emit(F_LDA, n->u.integer.a);
     if(flags & WANT_LVALUE)
     {
-      emit(F_EXTERNAL_LVALUE, n->u.integer.b);
+      emit2(F_EXTERNAL_LVALUE, n->u.integer.b,n->u.integer.a);
       return 2;
     }else{
-      emit(F_EXTERNAL, n->u.integer.b);
+      emit2(F_EXTERNAL, n->u.integer.b,n->u.integer.a);
       return 1;
     }
     break;
 
   case F_UNDEFINED:
     yyerror("Undefined identifier");
-    emit(F_NUMBER,0);
+    emit1(F_NUMBER,0);
     return 1;
 
   case F_PUSH_ARRAY:
     code_expression(CAR(n), 0, "`@");
-    emit2(F_PUSH_ARRAY);
+    emit0(F_PUSH_ARRAY);
     return -0x7ffffff;
 
   case '?':
@@ -298,7 +298,7 @@ static int do_docode2(node *n,int flags)
       tmp1=alloc_label();
       do_jump_when_zero(CAR(n), tmp1);
       DO_CODE_BLOCK(CADR(n));
-      emit(F_LABEL, tmp1);
+      emit1(F_LABEL, tmp1);
       current_switch_jumptable = prev_switch_jumptable;
       return 0;
     }
@@ -308,7 +308,7 @@ static int do_docode2(node *n,int flags)
       tmp1=alloc_label();
       do_jump_when_non_zero(CAR(n), tmp1);
       DO_CODE_BLOCK(CDDR(n));
-      emit(F_LABEL,tmp1);
+      emit1(F_LABEL,tmp1);
       current_switch_jumptable = prev_switch_jumptable;
       return 0;
     }
@@ -317,11 +317,11 @@ static int do_docode2(node *n,int flags)
     do_jump_when_zero(CAR(n),tmp1);
 
     adroppings=do_docode(CADR(n), flags);
-    tmp3=emit(F_POP_N_ELEMS,0);
+    tmp3=emit1(F_POP_N_ELEMS,0);
 
     /* Else */
     tmp2=do_jump(F_BRANCH,-1);
-    emit(F_LABEL, tmp1);
+    emit1(F_LABEL, tmp1);
 
     bdroppings=do_docode(CDDR(n), flags);
     if(adroppings < bdroppings)
@@ -335,7 +335,7 @@ static int do_docode2(node *n,int flags)
       adroppings=bdroppings;
     }
 
-    emit(F_LABEL, tmp2);
+    emit1(F_LABEL, tmp2);
 
     current_switch_jumptable = prev_switch_jumptable;
     return adroppings;
@@ -362,33 +362,33 @@ static int do_docode2(node *n,int flags)
        match_types(CAR(n)->type,object_type_string))
     {
       code_expression(CDR(n), 0, "assignment");
-      emit2(F_LTOSVAL2);
+      emit0(F_LTOSVAL2);
     }else{
-      emit2(F_LTOSVAL);
+      emit0(F_LTOSVAL);
       code_expression(CDR(n), 0, "assignment");
     }
 
 
     switch(n->token)
     {
-    case F_ADD_EQ: emit2(F_ADD); break;
-    case F_AND_EQ: emit2(F_AND); break;
-    case F_OR_EQ:  emit2(F_OR);  break;
-    case F_XOR_EQ: emit2(F_XOR); break;
-    case F_LSH_EQ: emit2(F_LSH); break;
-    case F_RSH_EQ: emit2(F_RSH); break;
-    case F_SUB_EQ: emit2(F_SUBTRACT); break;
-    case F_MULT_EQ:emit2(F_MULTIPLY);break;
-    case F_MOD_EQ: emit2(F_MOD); break;
-    case F_DIV_EQ: emit2(F_DIVIDE); break;
+    case F_ADD_EQ: emit0(F_ADD); break;
+    case F_AND_EQ: emit0(F_AND); break;
+    case F_OR_EQ:  emit0(F_OR);  break;
+    case F_XOR_EQ: emit0(F_XOR); break;
+    case F_LSH_EQ: emit0(F_LSH); break;
+    case F_RSH_EQ: emit0(F_RSH); break;
+    case F_SUB_EQ: emit0(F_SUBTRACT); break;
+    case F_MULT_EQ:emit0(F_MULTIPLY);break;
+    case F_MOD_EQ: emit0(F_MOD); break;
+    case F_DIV_EQ: emit0(F_DIVIDE); break;
     }
 
     if(flags & DO_POP)
     {
-      emit2(F_ASSIGN_AND_POP);
+      emit0(F_ASSIGN_AND_POP);
       return 0;
     }else{
-      emit2(F_ASSIGN);
+      emit0(F_ASSIGN);
       return 1;
     }
 
@@ -412,15 +412,15 @@ static int do_docode2(node *n,int flags)
 	   match_types(CDR(n)->type,string_type_string))
 	{
 	  code_expression(CDAR(n), 0, "binary operand");
-	  emit2(F_LTOSVAL2);
+	  emit0(F_LTOSVAL2);
 	}else{
-	  emit2(F_LTOSVAL);
+	  emit0(F_LTOSVAL);
 	  code_expression(CDAR(n), 0, "binary operand");
 	}
 
-	emit2(CAR(n)->token);
+	emit0(CAR(n)->token);
 
-	emit2(n->token);
+	emit0(n->token);
 	return n->token==F_ASSIGN;
       }
 
@@ -435,7 +435,7 @@ static int do_docode2(node *n,int flags)
 	if(CDR(n)->u.integer.b) goto normal_assign;
 
 	code_expression(CAR(n), 0, "RHS");
-	emit(flags & DO_POP ? F_ASSIGN_LOCAL_AND_POP:F_ASSIGN_LOCAL,
+	emit1(flags & DO_POP ? F_ASSIGN_LOCAL_AND_POP:F_ASSIGN_LOCAL,
 	     CDR(n)->u.integer.a );
 	break;
 
@@ -445,7 +445,7 @@ static int do_docode2(node *n,int flags)
 	  yyerror("Cannot assign functions or constants.\n");
 	}else{
 	  code_expression(CAR(n), 0, "RHS");
-	  emit(flags & DO_POP ? F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL,
+	  emit1(flags & DO_POP ? F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL,
 	       CDR(n)->u.id.number);
 	}
 	break;
@@ -454,7 +454,7 @@ static int do_docode2(node *n,int flags)
       normal_assign:
 	tmp1=do_docode(CDR(n),DO_LVALUE);
 	if(do_docode(CAR(n),0)!=1) yyerror("RHS is void!");
-	emit2(flags & DO_POP ? F_ASSIGN_AND_POP:F_ASSIGN);
+	emit0(flags & DO_POP ? F_ASSIGN_AND_POP:F_ASSIGN);
 	break;
       }
       return flags & DO_POP ? 0 : 1;
@@ -465,7 +465,7 @@ static int do_docode2(node *n,int flags)
     tmp1=alloc_label();
     do_cond_jump(CAR(n), tmp1, n->token == F_LOR, 0);
     code_expression(CDR(n), flags, n->token == F_LOR ? "||" : "&&");
-    emit(F_LABEL,tmp1);
+    emit1(F_LABEL,tmp1);
     return 1;
 
   case F_EQ:
@@ -493,7 +493,7 @@ static int do_docode2(node *n,int flags)
     tmp1=do_docode(CAR(n),DO_NOT_COPY);
     if(do_docode(CDR(n),DO_NOT_COPY)!=2)
       fatal("Compiler internal error (at %ld).\n",(long)lex.current_line);
-    emit2(n->token);
+    emit0(n->token);
     return tmp1;
 
   case F_INC:
@@ -506,10 +506,10 @@ static int do_docode2(node *n,int flags)
 
     if(flags & DO_POP)
     {
-      emit2(F_INC_AND_POP);
+      emit0(F_INC_AND_POP);
       return 0;
     }else{
-      emit2(n->token);
+      emit0(n->token);
       return 1;
     }
 
@@ -522,10 +522,10 @@ static int do_docode2(node *n,int flags)
 #endif
     if(flags & DO_POP)
     {
-      emit2(F_DEC_AND_POP);
+      emit0(F_DEC_AND_POP);
       return 0;
     }else{
-      emit2(n->token);
+      emit0(n->token);
       return 1;
     }
 
@@ -589,7 +589,7 @@ static int do_docode2(node *n,int flags)
       }
     }
     tmp2=do_docode(CAR(n),DO_NOT_COPY);
-    emit2(F_CONST0);
+    emit0(F_CONST0);
 
   foreach_arg_pushed:
 #ifdef PIKE_DEBUG
@@ -598,19 +598,19 @@ static int do_docode2(node *n,int flags)
      * think it is worth it.
      */
     if(d_flag)
-      emit2(F_MARK);
+      emit0(F_MARK);
 #endif
     tmp3=do_jump(F_BRANCH,-1);
     tmp1=ins_label(-1);
     DO_CODE_BLOCK(CDR(n));
     ins_label(current_continue);
-    emit(F_LABEL,tmp3);
+    emit1(F_LABEL,tmp3);
     do_jump(n->token,tmp1);
     ins_label(current_break);
 
 #ifdef PIKE_DEBUG
     if(d_flag)
-      emit2(F_POP_MARK);
+      emit0(F_POP_MARK);
 #endif
 
     current_switch_jumptable = prev_switch_jumptable;
@@ -640,19 +640,19 @@ static int do_docode2(node *n,int flags)
      * think it is worth it.
      */
     if(d_flag)
-      emit2(F_MARK);
+      emit0(F_MARK);
 #endif
     tmp3=do_jump(F_BRANCH,-1);
     tmp1=ins_label(-1);
 
     DO_CODE_BLOCK(CDR(n));
     ins_label(current_continue);
-    emit(F_LABEL,tmp3);
+    emit1(F_LABEL,tmp3);
     do_jump(n->token,tmp1);
     ins_label(current_break);
 #ifdef PIKE_DEBUG
     if(d_flag)
-      emit2(F_POP_MARK);
+      emit0(F_POP_MARK);
 #endif
 
     current_switch_jumptable = prev_switch_jumptable;
@@ -697,23 +697,23 @@ static int do_docode2(node *n,int flags)
       return 0;
     }
     tmp1=store_prog_string(n->type);
-    emit(F_STRING,tmp1);
+    emit1(F_STRING,tmp1);
 
     tmp1=do_docode(CAR(n),0);
-    if(!tmp1) { emit2(F_CONST0); tmp1=1; }
+    if(!tmp1) { emit0(F_CONST0); tmp1=1; }
     if(tmp1>1) do_pop(tmp1-1);
 
-    emit2(F_CAST);
+    emit0(F_CAST);
     return 1;
 
   case F_SOFT_CAST:
     if (runtime_options & RUNTIME_CHECK_TYPES) {
       tmp1 = store_prog_string(n->type);
-      emit(F_STRING, tmp1);
+      emit1(F_STRING, tmp1);
       tmp1 = do_docode(CAR(n), 0);
-      if (!tmp1) { emit2(F_CONST0); tmp1 = 1; }
+      if (!tmp1) { emit0(F_CONST0); tmp1 = 1; }
       if (tmp1 > 1) do_pop(tmp1 - 1);
-      emit2(F_SOFT_CAST);
+      emit0(F_SOFT_CAST);
       return 1;
     }
     tmp1 = do_docode(CAR(n), flags);
@@ -730,12 +730,12 @@ static int do_docode2(node *n,int flags)
 	  if(!CAR(n)->u.sval.u.efun->docode || 
 	     !CAR(n)->u.sval.u.efun->docode(n))
 	  {
-	    emit2(F_MARK);
+	    emit0(F_MARK);
 	    do_docode(CDR(n),0);
 	    tmp1=store_constant(& CAR(n)->u.sval,
 				!(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND),
 				CAR(n)->name);
-	    emit(F_APPLY,tmp1);
+	    emit1(F_APPLY,tmp1);
 	  }
 	  if(n->type == void_type_string)
 	    return 0;
@@ -744,29 +744,29 @@ static int do_docode2(node *n,int flags)
 	}else{
 	  if(CAR(n)->u.sval.u.object == fake_object)
 	  {
-	    emit2(F_MARK);
+	    emit0(F_MARK);
 	    do_docode(CDR(n),0);
-	    emit(F_CALL_LFUN, CAR(n)->u.sval.subtype);
+	    emit1(F_CALL_LFUN, CAR(n)->u.sval.subtype);
 	    return 1;
 	  }
        	}
       }
 
-      emit2(F_MARK);
+      emit0(F_MARK);
       do_docode(CDR(n),0);
       tmp1=store_constant(& CAR(n)->u.sval,
 			  !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND),
 			  CAR(n)->name);
-      emit(F_APPLY,tmp1);
+      emit1(F_APPLY,tmp1);
       
       return 1;
     }
     else if(CAR(n)->token == F_IDENTIFIER &&
 	    IDENTIFIER_IS_FUNCTION(ID_FROM_INT(new_program, CAR(n)->u.id.number)->identifier_flags))
     {
-      emit2(F_MARK);
+      emit0(F_MARK);
       do_docode(CDR(n),0);
-      emit(F_CALL_LFUN, CAR(n)->u.id.number);
+      emit1(F_CALL_LFUN, CAR(n)->u.id.number);
       return 1;
     }
     else
@@ -775,7 +775,7 @@ static int do_docode2(node *n,int flags)
       struct efun *fun;
       node *foo;
 
-      emit2(F_MARK);
+      emit0(F_MARK);
       do_docode(CAR(n),0);
       do_docode(CDR(n),0);
 
@@ -790,11 +790,11 @@ static int do_docode2(node *n,int flags)
 	   foo->u.sval.subtype == FUNCTION_BUILTIN &&
 	   foo->u.sval.u.efun->function == f_call_function)
 	{
-	  emit2(F_CALL_FUNCTION);
+	  emit0(F_CALL_FUNCTION);
 	}else{
 	  /* We might want to put "predef::"+foo->name here /Hubbe */
 	  tmp1=store_constant(& foo->u.sval, 1, foo->name);
-	  emit(F_APPLY, tmp1);
+	  emit1(F_APPLY, tmp1);
 	}
       }
       free_node(foo);
@@ -846,8 +846,8 @@ static int do_docode2(node *n,int flags)
 
     cases=count_cases(CDR(n));
 
-    tmp1=emit(F_SWITCH,0);
-    emit(F_ALIGN,sizeof(INT32));
+    tmp1=emit1(F_SWITCH,0);
+    emit1(F_ALIGN,sizeof(INT32));
 
     current_switch_values_on_stack=0;
     current_switch_case=1;
@@ -857,7 +857,7 @@ static int do_docode2(node *n,int flags)
 
     for(e=1; e<cases*2+2; e++)
     {
-      jumptable[e]=emit(F_POINTER, 0);
+      jumptable[e]=emit1(F_POINTER, 0);
       current_switch_jumptable[e]=-1;
     }
 
@@ -918,7 +918,7 @@ static int do_docode2(node *n,int flags)
     current_switch_values_on_stack = prev_switch_values_on_stack;
     current_switch_type = prev_switch_type;
 
-    emit(F_LABEL, current_break);
+    emit1(F_LABEL, current_break);
 
     current_break=break_save;
 #ifdef PIKE_DEBUG
@@ -1043,13 +1043,13 @@ static int do_docode2(node *n,int flags)
 
   case F_RETURN:
     do_docode(CAR(n),0);
-    emit2(F_RETURN);
+    emit0(F_RETURN);
     return 0;
 
   case F_SSCANF:
     tmp1=do_docode(CAR(n),DO_NOT_COPY);
     tmp2=do_docode(CDR(n),DO_NOT_COPY | DO_LVALUE);
-    emit(F_SSCANF,tmp1+tmp2);
+    emit1(F_SSCANF,tmp1+tmp2);
     return 1;
 
   case F_CATCH:
@@ -1066,7 +1066,7 @@ static int do_docode2(node *n,int flags)
     DO_CODE_BLOCK(CAR(n));
     ins_label(current_continue);
     ins_label(current_break);
-    emit2(F_THROW_ZERO);
+    emit0(F_THROW_ZERO);
     ins_label(tmp1);
 
     current_break=break_save;
@@ -1084,7 +1084,7 @@ static int do_docode2(node *n,int flags)
       if(tmp1 & 1)
 	fatal("Very internal compiler error.\n");
 #endif
-      emit(F_ARRAY_LVALUE, tmp1>>1);
+      emit1(F_ARRAY_LVALUE, tmp1>>1);
       return 2;
 
   case F_ARROW:
@@ -1094,16 +1094,16 @@ static int do_docode2(node *n,int flags)
     {
       /* FIXME!!!! ??? I wonder what needs fixing... /Hubbe */
       tmp1=do_docode(CAR(n), 0);
-      emit(F_ARROW_STRING, store_prog_string(CDR(n)->u.sval.u.string));
+      emit1(F_ARROW_STRING, store_prog_string(CDR(n)->u.sval.u.string));
       return 2;
     }else{
       tmp1=do_docode(CAR(n), DO_NOT_COPY);
-      emit(F_ARROW, store_prog_string(CDR(n)->u.sval.u.string));
+      emit1(F_ARROW, store_prog_string(CDR(n)->u.sval.u.string));
       if(!(flags & DO_NOT_COPY))
       {
 	while(n && (n->token==F_INDEX || n->token==F_ARROW)) n=CAR(n);
 	if(n->token==F_CONSTANT && !(n->node_info & OPT_EXTERNAL_DEPEND))
-	  emit2(F_COPY_VALUE);
+	  emit0(F_COPY_VALUE);
       }
     }
     return tmp1;
@@ -1120,14 +1120,14 @@ static int do_docode2(node *n,int flags)
 	if(!mklval)
 	  fatal("Unwanted lvalue!\n");
 #endif
-	emit2(F_INDIRECT);
+	emit0(F_INDIRECT);
       }
       
       if(do_docode(CDR(n),0) != 1)
 	fatal("Internal compiler error, please report this (1).");
       if(CDR(n)->token != F_CONSTANT &&
 	match_types(CDR(n)->type, string_type_string))
-	emit2(F_CLEAR_STRING_SUBTYPE);
+	emit0(F_CLEAR_STRING_SUBTYPE);
       return 2;
     }else{
       tmp1=do_docode(CAR(n), DO_NOT_COPY);
@@ -1135,15 +1135,15 @@ static int do_docode2(node *n,int flags)
       code_expression(CDR(n), DO_NOT_COPY, "index");
       if(CDR(n)->token != F_CONSTANT &&
 	match_types(CDR(n)->type, string_type_string))
-	emit2(F_CLEAR_STRING_SUBTYPE);
+	emit0(F_CLEAR_STRING_SUBTYPE);
 
-      emit2(F_INDEX);
+      emit0(F_INDEX);
 
       if(!(flags & DO_NOT_COPY))
       {
 	while(n && (n->token==F_INDEX || n->token==F_ARROW)) n=CAR(n);
 	if(n->token==F_CONSTANT && !(n->node_info & OPT_EXTERNAL_DEPEND))
-	  emit2(F_COPY_VALUE);
+	  emit0(F_COPY_VALUE);
       }
     }
     return tmp1;
@@ -1154,15 +1154,15 @@ static int do_docode2(node *n,int flags)
     case T_INT:
       if(!n->u.sval.u.integer && n->u.sval.subtype==NUMBER_UNDEFINED)
       {
-	emit2(F_UNDEFINED);
+	emit0(F_UNDEFINED);
       }else{
-	emit(F_NUMBER,n->u.sval.u.integer);
+	emit1(F_NUMBER,n->u.sval.u.integer);
       }
       return 1;
 
     case T_STRING:
       tmp1=store_prog_string(n->u.sval.u.string);
-      emit(F_STRING,tmp1);
+      emit1(F_STRING,tmp1);
       return 1;
 
     case T_FUNCTION:
@@ -1170,7 +1170,7 @@ static int do_docode2(node *n,int flags)
       {
 	if(n->u.sval.u.object == fake_object)
 	{
-	  emit(F_LFUN,n->u.sval.subtype);
+	  emit1(F_LFUN,n->u.sval.subtype);
 	  return 1;
 	}
 
@@ -1181,8 +1181,7 @@ static int do_docode2(node *n,int flags)
 	  
 	  for(o=fake_object->parent;o!=n->u.sval.u.object;o=o->parent)
 	    x++;
-	  emit(F_LDA, x);
-	  emit(F_EXTERNAL, n->u.sval.subtype);
+	  emit2(F_EXTERNAL, n->u.sval.subtype,x);
 	  new_program->flags |= PROGRAM_USES_PARENT;
 	  return 1;
 	}
@@ -1198,7 +1197,7 @@ static int do_docode2(node *n,int flags)
       tmp1=store_constant(&(n->u.sval),
 			  !(n->tree_info & OPT_EXTERNAL_DEPEND),
 			  n->name);
-      emit(F_CONSTANT,tmp1);
+      emit1(F_CONSTANT,tmp1);
       return 1;
 
     case T_ARRAY:
@@ -1207,11 +1206,11 @@ static int do_docode2(node *n,int flags)
       tmp1=store_constant(&(n->u.sval),
 			  !(n->tree_info & OPT_EXTERNAL_DEPEND),
 			  n->name);
-      emit(F_CONSTANT,tmp1);
+      emit1(F_CONSTANT,tmp1);
       
       /* copy now or later ? */
       if(!(flags & DO_NOT_COPY) && !(n->tree_info & OPT_EXTERNAL_DEPEND))
-	emit2(F_COPY_VALUE);
+	emit0(F_COPY_VALUE);
       return 1;
 
     }
@@ -1223,28 +1222,27 @@ static int do_docode2(node *n,int flags)
 
     if(n->u.integer.b)
     {
-      emit(F_LDA,n->u.integer.b);
       if(flags & WANT_LVALUE)
       {
-	emit(F_LEXICAL_LOCAL_LVALUE,n->u.id.number);
+	emit2(F_LEXICAL_LOCAL_LVALUE,n->u.id.number,n->u.integer.b);
 	return 2;
       }else{
-	emit(F_LEXICAL_LOCAL,n->u.id.number);
+	emit2(F_LEXICAL_LOCAL,n->u.id.number,n->u.integer.b);
 	return 1;
       }
     }else{
       if(flags & WANT_LVALUE)
       {
-	emit(F_LOCAL_LVALUE,n->u.id.number);
+	emit1(F_LOCAL_LVALUE,n->u.id.number);
 	return 2;
       }else{
-	emit(F_LOCAL,n->u.id.number);
+	emit1(F_LOCAL,n->u.id.number);
 	return 1;
       }
     }
 
     case F_TRAMPOLINE:
-      emit(F_TRAMPOLINE,n->u.id.number);
+      emit1(F_TRAMPOLINE,n->u.id.number);
       return 1;
 
   case F_IDENTIFIER:
@@ -1254,15 +1252,15 @@ static int do_docode2(node *n,int flags)
       {
 	yyerror("Cannot assign functions.\n");
       }else{
-	emit(F_LFUN,n->u.id.number);
+	emit1(F_LFUN,n->u.id.number);
       }
     }else{
       if(flags & WANT_LVALUE)
       {
-	emit(F_GLOBAL_LVALUE,n->u.id.number);
+	emit1(F_GLOBAL_LVALUE,n->u.id.number);
 	return 2;
       }else{
-	emit(F_GLOBAL,n->u.id.number);
+	emit1(F_GLOBAL,n->u.id.number);
       }
     }
     return 1;
diff --git a/src/docode.h b/src/docode.h
index f2e2beb8bc..b75413422c 100644
--- a/src/docode.h
+++ b/src/docode.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: docode.h,v 1.8 2000/03/07 21:22:08 hubbe Exp $
+ * $Id: docode.h,v 1.9 2000/04/20 02:41:44 hubbe Exp $
  */
 #ifndef DOCODE_H
 #define DOCODE_H
@@ -21,8 +21,9 @@
 
 extern int store_linenumbers;
 
-#define emit(X,Y) insert_opcode((X),(Y),lex.current_line, lex.current_file)
-#define emit2(X) insert_opcode2((X),lex.current_line, lex.current_file)
+#define emit0(X)     insert_opcode0((X),lex.current_line, lex.current_file)
+#define emit1(X,Y)   insert_opcode1((X),(Y),lex.current_line, lex.current_file)
+#define emit2(X,Y,Z) insert_opcode2((X),(Y),(Z),lex.current_line, lex.current_file)
 
 /* Prototypes begin here */
 void upd_int(int offset, INT32 tmp);
diff --git a/src/error.h b/src/error.h
index f27781e076..2aa412db11 100644
--- a/src/error.h
+++ b/src/error.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: error.h,v 1.40 2000/02/17 00:31:08 hubbe Exp $
+ * $Id: error.h,v 1.41 2000/04/20 02:41:44 hubbe Exp $
  */
 #ifndef ERROR_H
 #define ERROR_H
@@ -229,7 +229,7 @@ void cleanup_error(void);
 /* Prototypes end here */
 
 #define fatal \
- fprintf(stderr,"Fatal error at %s:%d\n",__FILE__,__LINE__),debug_fatal
+ fprintf(stderr,"%s:%d: Fatal error:\n",__FILE__,__LINE__),debug_fatal
 
 /* Some useful error macros. */
 
diff --git a/src/gc.c b/src/gc.c
index 0038baea05..d79bfb736d 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -29,7 +29,7 @@ struct callback *gc_evaluator_callback=0;
 
 #include "block_alloc.h"
 
-RCSID("$Id: gc.c,v 1.74 2000/04/20 01:49:42 mast Exp $");
+RCSID("$Id: gc.c,v 1.75 2000/04/20 02:41:44 hubbe Exp $");
 
 /* Run garbage collect approximate every time we have
  * 20 percent of all arrays, objects and programs is
@@ -953,10 +953,18 @@ void do_gc(void)
 #endif
   Pike_in_gc=5;
   /* Now we free the unused stuff */
+
+  /* We do the objects first, that way destroy()
+   * won't have to worry about zapped arrays and mappings
+   */
+  gc_free_all_unreferenced_objects();
+
   gc_free_all_unreferenced_arrays();
   gc_free_all_unreferenced_multisets();
   gc_free_all_unreferenced_mappings();
   gc_free_all_unreferenced_programs();
+<<<<<<< gc.c
+=======
   Pike_in_gc=4;
   /* This is intended to happen before the freeing done above. But
    * it's put here for the time being, since the problem of non-object
@@ -965,6 +973,7 @@ void do_gc(void)
   destroyed = gc_destroy_all_unreferenced_objects();
   Pike_in_gc=5;
   destructed = gc_free_all_unreferenced_objects();
+>>>>>>> 1.74
 
 #ifdef PIKE_DEBUG
   if (destroyed != destructed)
diff --git a/src/interpret_functions.h b/src/interpret_functions.h
index da58086500..d943e41dc1 100644
--- a/src/interpret_functions.h
+++ b/src/interpret_functions.h
@@ -1,5 +1,5 @@
 /*
- * $Id: interpret_functions.h,v 1.9 2000/04/19 20:20:01 grubba Exp $
+ * $Id: interpret_functions.h,v 1.10 2000/04/20 02:41:44 hubbe Exp $
  *
  * Opcode definitions for the interpreter.
  */
@@ -102,7 +102,7 @@ OPCODE1(F_GLOBAL,"global")
 BREAK;
 
 
-OPCODE1ACC(F_EXTERNAL,"external")
+OPCODE2(F_EXTERNAL,"external")
 {
   struct inherit *inherit;
   struct program *p;
@@ -130,7 +130,7 @@ OPCODE1ACC(F_EXTERNAL,"external")
       
       i=o->parent_identifier;
       o=o->parent;
-      acc+=inherit->parent_offset-1;
+      arg2+=inherit->parent_offset-1;
     }else{
 #ifdef PIKE_DEBUG
       if(t_flag>4)
@@ -183,8 +183,8 @@ OPCODE1ACC(F_EXTERNAL,"external")
     }
 #endif /* DEBUG_MALLOC */
     
-    if(!acc) break;
-    --acc;
+    if(!arg2) break;
+    --arg2;
   }
   
   low_object_index_no_free(Pike_sp,
@@ -196,49 +196,51 @@ OPCODE1ACC(F_EXTERNAL,"external")
 }
 BREAK;
 
-      CASE(F_EXTERNAL_LVALUE);
-      {
-	struct inherit *inherit;
-	struct program *p;
-	struct object *o;
-	INT32 i,id=GET_ARG();
-
-	inherit=&Pike_fp->context;
-	o=Pike_fp->current_object;
-	
-	if(!o)
-	  error("Current object is destructed\n");
-
-	while(1)
-	{
-	  if(inherit->parent_offset)
-	  {
-	    i=o->parent_identifier;
-	    o=o->parent;
-	    accumulator+=inherit->parent_offset-1;
-	  }else{
-	    i=inherit->parent_identifier;
-	    o=inherit->parent;
-	  }
-
-	  if(!o)
-	    error("Parent no longer exists\n");
-
-	  if(!(p=o->prog))
-	    error("Attempting to access variable in destructed object\n");
-
-	  inherit=INHERIT_FROM_INT(p, i);
-
-	  if(!accumulator) break;
-	  accumulator--;
-	}
+OPCODE2(F_EXTERNAL_LVALUE,"& external")
+{
+  struct inherit *inherit;
+  struct program *p;
+  struct object *o;
+  INT32 i,id=arg1;
+  
+  inherit=&Pike_fp->context;
+  o=Pike_fp->current_object;
+  
+  if(!o)
+    error("Current object is destructed\n");
+  
+  while(1)
+  {
+    if(inherit->parent_offset)
+    {
+      i=o->parent_identifier;
+      o=o->parent;
+      arg2+=inherit->parent_offset-1;
+    }else{
+      i=inherit->parent_identifier;
+      o=inherit->parent;
+    }
+    
+    if(!o)
+      error("Parent no longer exists\n");
+    
+    if(!(p=o->prog))
+      error("Attempting to access variable in destructed object\n");
+    
+    inherit=INHERIT_FROM_INT(p, i);
+    
+    if(!arg2) break;
+    arg2--;
+  }
+  
+  ref_push_object(o);
+  Pike_sp->type=T_LVALUE;
+  Pike_sp->u.integer=id + inherit->identifier_level;
+  Pike_sp++;
+  break;
+}
 
-	ref_push_object(o);
-	Pike_sp->type=T_LVALUE;
-	Pike_sp->u.integer=id + inherit->identifier_level;
-	Pike_sp++;
-	break;
-      }
+BREAK;
 
 
       CASE(F_MARK_AND_LOCAL); *(Pike_mark_sp++)=Pike_sp;
@@ -254,11 +256,8 @@ OPCODE2(F_2_LOCALS, "2 locals")
   print_return_value();
 BREAK;
 
-OPCODE2(F_LOCAL_2_LOCAL, "local=local;")
-{
-  int tmp=arg1;
-  assign_svalue(Pike_fp->locals + tmp, Pike_fp->locals + arg2);
-}
+OPCODE2(F_LOCAL_2_LOCAL, "local = local")
+  assign_svalue(Pike_fp->locals+arg1, Pike_fp->locals+arg2);
 BREAK;
 
 OPCODE2(F_LOCAL_2_GLOBAL, "global=local;")
@@ -284,12 +283,11 @@ OPCODE2(F_LOCAL_2_GLOBAL, "global=local;")
 }
 BREAK;
 
-OPCODE2(F_GLOBAL_2_LOCAL, "local=global;")
+OPCODE2(F_GLOBAL_2_LOCAL,"global = local")
 {
-  INT32 tmp = arg1 + Pike_fp->context.identifier_level;
-  INT32 tmp2 = arg2;
-  free_svalue(Pike_fp->locals + tmp2);
-  low_object_index_no_free(Pike_fp->locals + tmp2,
+  INT32 tmp=arg1 + Pike_fp->context.identifier_level;
+  free_svalue(Pike_fp->locals + arg2);
+  low_object_index_no_free(Pike_fp->locals + arg2,
 			   Pike_fp->current_object,
 			   tmp);
 }
@@ -302,31 +300,34 @@ OPCODE1(F_LOCAL_LVALUE, "& local")
   Pike_sp += 2;
 BREAK;
 
-OPCODE1ACC(F_LEXICAL_LOCAL, "lexical local")
+OPCODE2(F_LEXICAL_LOCAL,"lexical local")
 {
-  struct pike_frame *f = Pike_fp;
-  while(acc--)
+  struct pike_frame *f=Pike_fp;
+  while(arg2--)
   {
     f=f->scope;
     if(!f) error("Lexical scope error.\n");
   }
   push_svalue(f->locals + arg1);
   print_return_value();
+  break;
 }
 BREAK;
 
-OPCODE1ACC(F_LEXICAL_LOCAL_LVALUE, "& lexical local")
+
+OPCODE2(F_LEXICAL_LOCAL_LVALUE,"&lexical local")
 {
-  struct pike_frame *f = Pike_fp;
-  while(acc--)
+  struct pike_frame *f=Pike_fp;
+  while(arg2--)
   {
-    f = f->scope;
+    f=f->scope;
     if(!f) error("Lexical scope error.\n");
   }
-  Pike_sp[0].type = T_LVALUE;
-  Pike_sp[0].u.lval = f->locals+arg1;
-  Pike_sp[1].type = T_VOID;
-  Pike_sp += 2;
+  Pike_sp[0].type=T_LVALUE;
+  Pike_sp[0].u.lval=f->locals+arg1;
+  Pike_sp[1].type=T_VOID;
+  Pike_sp+=2;
+  break;
 }
 BREAK;
 
@@ -520,10 +521,8 @@ OPCODE1(F_GLOBAL_LVALUE, "& global")
 {
   struct identifier *i;
   INT32 tmp=arg1 + Pike_fp->context.identifier_level;
-
   if(!Pike_fp->current_object->prog)
     error("Cannot access global variables in destructed object.\n");
-
   i=ID_FROM_INT(Pike_fp->current_object->prog, tmp);
 
   if(!IDENTIFIER_IS_VARIABLE(i->identifier_flags))
@@ -542,6 +541,7 @@ OPCODE1(F_GLOBAL_LVALUE, "& global")
   Pike_sp+=2;
 }
 BREAK;
+
       
 OPCODE0(F_INC, "++x")
 {
@@ -655,6 +655,7 @@ OPCODE0(F_POST_INC, "x++")
 }
 BREAK;
 
+
 OPCODE0(F_POST_DEC, "x--")
 {
   union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT);
@@ -679,6 +680,10 @@ OPCODE0(F_POST_DEC, "x--")
 }
 BREAK;
 
+OPCODE1(F_ASSIGN_LOCAL,"assign local")
+  assign_svalue(Pike_fp->locals+arg1,Pike_sp-1);
+BREAK;
+
 OPCODE0(F_ASSIGN, "assign")
   assign_lvalue(Pike_sp-3,Pike_sp-1);
   free_svalue(Pike_sp-3);
@@ -687,22 +692,23 @@ OPCODE0(F_ASSIGN, "assign")
   Pike_sp-=2;
 BREAK;
 
+OPCODE2(F_APPLY_ASSIGN_LOCAL_AND_POP,"apply, assign local and pop")
+  strict_apply_svalue(Pike_fp->context.prog->constants + arg1, Pike_sp - *--Pike_mark_sp );
+  free_svalue(Pike_fp->locals+arg2);
+  Pike_fp->locals[arg2]=Pike_sp[-1];
+  Pike_sp--;
+BREAK;
+
+OPCODE2(F_APPLY_ASSIGN_LOCAL,"apply, assign local")
+  strict_apply_svalue(Pike_fp->context.prog->constants + arg1, Pike_sp - *--Pike_mark_sp );
+  assign_svalue(Pike_fp->locals+arg2,Pike_sp-1);
+BREAK;
+
 OPCODE0(F_ASSIGN_AND_POP, "assign and pop")
   assign_lvalue(Pike_sp-3, Pike_sp-1);
   pop_n_elems(3);
 BREAK;
 
-    CASE(F_APPLY_ASSIGN_LOCAL);
-      strict_apply_svalue(Pike_fp->context.prog->constants + GET_ARG(), Pike_sp - *--Pike_mark_sp );
-      /* Fall through */
-
-      CASE(F_ASSIGN_LOCAL);
-      assign_svalue(Pike_fp->locals+GET_ARG(),Pike_sp-1);
-      break;
-
-    CASE(F_APPLY_ASSIGN_LOCAL_AND_POP);
-      strict_apply_svalue(Pike_fp->context.prog->constants + GET_ARG(), Pike_sp - *--Pike_mark_sp );
-      /* Fall through */
 
       CASE(F_ASSIGN_LOCAL_AND_POP);
       instr=GET_ARG();
@@ -758,6 +764,7 @@ OPCODE1(F_ASSIGN_GLOBAL_AND_POP, "assign global and pop")
 }
 BREAK;
 
+
 /* Stack machine stuff */
 
 OPCODE0(F_POP_VALUE, "pop")
@@ -1240,12 +1247,12 @@ BREAK;
       print_return_value();
       break;
 
-OPCODE1ACC(F_MAGIC_INDEX, "::`[]")
-  push_magic_index(magic_index_program, acc, arg1);
+OPCODE2(F_MAGIC_INDEX, "::`[]")
+  push_magic_index(magic_index_program, arg2, arg1);
 BREAK;
 
-OPCODE1ACC(F_MAGIC_SET_INDEX, "::`[]=")
-  push_magic_index(magic_set_index_program, acc, arg1);
+OPCODE2(F_MAGIC_SET_INDEX, "::`[]=")
+  push_magic_index(magic_set_index_program, arg2, arg1);
 BREAK;
 
 OPCODE0(F_CAST, "cast")
diff --git a/src/interpreter.h b/src/interpreter.h
index b98b728f7f..e6c2df64fd 100644
--- a/src/interpreter.h
+++ b/src/interpreter.h
@@ -9,19 +9,22 @@
   instr+=EXTRACT_UCHAR(pc++),\
   (t_flag>3 ? sprintf(trace_buffer,"-    Arg = %ld\n",(long)instr),write_to_stderr(trace_buffer,strlen(trace_buffer)) : 0),\
   instr))
+
 #define GET_ARG2() (\
-  instr=EXTRACT_UCHAR(pc++),\
+  instr=prefix2,\
+  prefix2=0,\
+  instr+=EXTRACT_UCHAR(pc++),\
   (t_flag>3 ? sprintf(trace_buffer,"-    Arg2= %ld\n",(long)instr),write_to_stderr(trace_buffer,strlen(trace_buffer)) : 0),\
   instr)
 
 #else
 #define GET_ARG() (instr=prefix,prefix=0,instr+EXTRACT_UCHAR(pc++))
-#define GET_ARG2() EXTRACT_UCHAR(pc++)
+#define GET_ARG2() (instr=prefix2,prefix2=0,instr+EXTRACT_UCHAR(pc++))
 #endif
 
 static int eval_instruction(unsigned char *pc)
 {
-  unsigned INT32 accumulator=0,instr, prefix=0;
+  unsigned INT32 prefix2=0,instr, prefix=0;
   debug_malloc_touch(Pike_fp);
   while(1)
   {
@@ -48,7 +51,7 @@ static int eval_instruction(unsigned char *pc)
       if(Pike_sp > Pike_evaluator_stack+Pike_stack_size)
 	fatal("Stack error (overflow).\n");
       
-      if(Pike_fp->fun>=0 && Pike_fp->current_object->prog &&
+      if(/* Pike_fp->fun>=0 && */ Pike_fp->current_object->prog &&
 	 Pike_fp->locals+Pike_fp->num_locals > Pike_sp)
 	fatal("Stack error (stupid!).\n");
 
@@ -124,7 +127,18 @@ static int eval_instruction(unsigned char *pc)
       prefix+=EXTRACT_UCHAR(pc++)<<8;
       break;
 
-      CASE(F_LDA); accumulator=GET_ARG(); break;
+      /* Support to allow large arguments */
+      CASE(F_PREFIX2_256); prefix2+=256; break;
+      CASE(F_PREFIX2_512); prefix2+=512; break;
+      CASE(F_PREFIX2_768); prefix2+=768; break;
+      CASE(F_PREFIX2_1024); prefix2+=1024; break;
+      CASE(F_PREFIX2_24BITX256);
+      prefix2+=EXTRACT_UCHAR(pc++)<<24;
+      CASE(F_PREFIX2_WORDX256);
+      prefix2+=EXTRACT_UCHAR(pc++)<<16;
+      CASE(F_PREFIX2_CHARX256);
+      prefix2+=EXTRACT_UCHAR(pc++)<<8;
+      break;
 
 
 #define INTERPRETER
@@ -133,17 +147,12 @@ static int eval_instruction(unsigned char *pc)
 #define OPCODE1(OP,DESC) CASE(OP); { \
   INT32 arg1=GET_ARG();
 
-#define OPCODE1ACC(OP,DESC) CASE(OP); { \
-  INT32 arg1=GET_ARG(); \
-  INT32 acc=accumulator;
-
 #define OPCODE2(OP,DESC) CASE(OP); { \
   INT32 arg1=GET_ARG(); \
   INT32 arg2=GET_ARG2();
 
 #define OPCODE0_TAIL(OP,DESC) CASE(OP);
 #define OPCODE1_TAIL(OP,DESC) CASE(OP);
-#define OPCODE1ACC_TAIL(OP,DESC) CASE(OP);
 #define OPCODE2_TAIL(OP,DESC) CASE(OP);
 
 
diff --git a/src/language.yacc b/src/language.yacc
index 17a7d2488b..b20a0652f8 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -11,10 +11,15 @@
  * called from Pike.
  */
 %token F_OFFSET
+
 %token F_PREFIX_256 F_PREFIX_512 F_PREFIX_768 F_PREFIX_1024
 %token F_PREFIX_CHARX256 F_PREFIX_WORDX256 F_PREFIX_24BITX256
+
+%token F_PREFIX2_256 F_PREFIX2_512 F_PREFIX2_768 F_PREFIX2_1024
+%token F_PREFIX2_CHARX256 F_PREFIX2_WORDX256 F_PREFIX2_24BITX256
+
 %token F_POP_VALUE F_POP_N_ELEMS F_MARK F_MARK2 F_MARK_X F_POP_MARK
-%token F_LDA F_CALL_LFUN F_CALL_LFUN_AND_POP F_CALL_LFUN_AND_RETURN
+%token F_CALL_LFUN F_CALL_LFUN_AND_POP F_CALL_LFUN_AND_RETURN
 %token F_APPLY F_APPLY_AND_POP F_MARK_APPLY F_MARK_APPLY_POP
 %token F_APPLY_AND_RETURN F_MARK_AND_STRING
 %token F_APPLY_ASSIGN_LOCAL F_APPLY_ASSIGN_LOCAL_AND_POP
@@ -164,7 +169,6 @@
 %token F_ALIGN
 %token F_POINTER
 %token F_LABEL
-%token F_BYTE
 %token F_DATA
 
 %token F_MAX_INSTR
@@ -188,7 +192,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.179 2000/04/08 02:01:08 hubbe Exp $");
+RCSID("$Id: language.yacc,v 1.180 2000/04/20 02:41:45 hubbe Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
diff --git a/src/lex.c b/src/lex.c
index 95bb509466..ed5879020b 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: lex.c,v 1.73 2000/04/19 20:20:16 grubba Exp $");
+RCSID("$Id: lex.c,v 1.74 2000/04/20 02:41:45 hubbe Exp $");
 #include "language.h"
 #include "array.h"
 #include "lex.h"
@@ -73,13 +73,11 @@ void exit_lex(void)
 
 #define OPCODE0(OP,DESC) { DESC, OP, 0 },
 #define OPCODE1(OP,DESC) { DESC, OP, I_HASARG },
-#define OPCODE1ACC(OP,DESC) { DESC, OP, I_TWO_ARGS },
-#define OPCODE2(OP,DESC) { DESC, OP, I_HASARG },
+#define OPCODE2(OP,DESC) { DESC, OP, I_TWO_ARGS },
 
 #define OPCODE0_TAIL(OP,DESC) { DESC, OP, 0 },
 #define OPCODE1_TAIL(OP,DESC) { DESC, OP, I_HASARG },
-#define OPCODE1ACC_TAIL(OP,DESC) { DESC, OP, I_TWO_ARGS },
-#define OPCODE2_TAIL(OP,DESC) { DESC, OP, I_HASARG },
+#define OPCODE2_TAIL(OP,DESC) { DESC, OP, I_TWO_ARGS },
 
 #define LEXER
 
@@ -115,7 +113,15 @@ struct keyword instr_names[]=
 { "arg+=256*XXX",	F_PREFIX_24BITX256,0 },
 { "arg+=512",		F_PREFIX_512,0 },
 { "arg+=768",		F_PREFIX_768,0 },
-{ "assign local",       F_ASSIGN_LOCAL, I_HASARG },
+
+{ "arg+=1024",		F_PREFIX2_1024,0 },
+{ "arg+=256",		F_PREFIX2_256,0 },
+{ "arg+=256*X",		F_PREFIX2_CHARX256,0 },
+{ "arg+=256*XX",	F_PREFIX2_WORDX256,0 },
+{ "arg+=256*XXX",	F_PREFIX2_24BITX256,0 },
+{ "arg+=512",		F_PREFIX2_512,0 },
+{ "arg+=768",		F_PREFIX2_768,0 },
+
 { "assign local and pop",	F_ASSIGN_LOCAL_AND_POP, I_HASARG },
 { "break",		F_BREAK,0 },	
 { "case",		F_CASE,0 },	
@@ -130,7 +136,7 @@ struct keyword instr_names[]=
 { "branch non zero",	F_BRANCH_WHEN_NON_ZERO, I_ISJUMP },	
 { "branch if local",	F_BRANCH_IF_LOCAL, I_HASARG },	
 { "branch if !local",	F_BRANCH_IF_NOT_LOCAL, I_HASARG },	
-{ "branch if ! local->x",	F_BRANCH_IF_NOT_LOCAL_ARROW, I_HASARG },	
+{ "branch if ! local->x",	F_BRANCH_IF_NOT_LOCAL_ARROW, I_TWO_ARGS },
 { "branch when zero",	F_BRANCH_WHEN_ZERO, I_ISJUMP },	
 { "branch if <",	F_BRANCH_WHEN_LT, I_ISJUMP },
 { "branch if >",	F_BRANCH_WHEN_GT, I_ISJUMP },
@@ -156,8 +162,6 @@ struct keyword instr_names[]=
 { "local function call",F_CALL_LFUN, I_HASARG },
 { "local function call and pop",F_CALL_LFUN_AND_POP, I_HASARG },
 { "local",		F_LOCAL, I_HASARG },	
-{ "& external",		F_EXTERNAL_LVALUE, I_HASARG },
-{ "LDA",			F_LDA, I_HASARG },
 { "mark & local",	F_MARK_AND_LOCAL, I_HASARG },	
 { "lvalue_list",	F_LVALUE_LIST,0 },	
 { "mark",               F_MARK,0 },
@@ -180,15 +184,12 @@ struct keyword instr_names[]=
 { "int index",          F_POS_INT_INDEX, I_HASARG },
 { "-int index",         F_NEG_INT_INDEX, I_HASARG },
 { "apply and pop",      F_APPLY_AND_POP, I_HASARG },
-{ "byte",               F_BYTE, I_HASARG },
 { "nop",                F_NOP,0 },
 { "add integer",        F_ADD_INT, I_HASARG },
 { "add -integer",       F_ADD_NEG_INT, I_HASARG },
 { "mark & call",        F_MARK_APPLY, I_HASARG },
 { "mark, call & pop",   F_MARK_APPLY_POP, I_HASARG },
 { "apply and return",   F_APPLY_AND_RETURN, I_HASARG },
-{ "apply, assign local and pop",   F_APPLY_ASSIGN_LOCAL_AND_POP, I_HASARG },
-{ "apply & assign local",   F_APPLY_ASSIGN_LOCAL, I_HASARG },
 { "call lfun & return", F_CALL_LFUN_AND_RETURN, I_HASARG },
 { "call function",      F_CALL_FUNCTION, 0 },
 { "call function & return", F_CALL_FUNCTION_AND_RETURN, 0 },
@@ -205,17 +206,44 @@ struct reserved
 void init_lex()
 {
   unsigned int i;
+#ifdef PIKE_DEBUG
+  int fatal_later=0;
+#endif
+
   for(i=0; i<NELEM(instr_names);i++)
   {
+#ifdef PIKE_DEBUG
     if(instr_names[i].token >= F_MAX_INSTR)
-      fatal("Error in instr_names[%u]\n\n",i);
+    {
+      fprintf(stderr,"Error in instr_names[%u]\n\n",i);
+      fatal_later++;
+    }
 
     if(instrs[instr_names[i].token - F_OFFSET].name)
-      fatal("Duplicate name for %s\n",instr_names[i].word);
+    {
+      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_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)
+    fatal("Found %d errors in instrs.\n",fatal_later);
+
+#endif
+
 }
 
 char *low_get_f_name(int n,struct program *p)
diff --git a/src/lex.h b/src/lex.h
index 82fb8c18cd..9295b18527 100644
--- a/src/lex.h
+++ b/src/lex.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: lex.h,v 1.14 2000/04/18 17:23:35 hubbe Exp $
+ * $Id: lex.h,v 1.15 2000/04/20 02:41:45 hubbe Exp $
  */
 #ifndef LEX_H
 #define LEX_H
@@ -25,7 +25,7 @@ struct keyword
 #define I_ISPOINTER 3
 #define I_ISJUMP 7
 #define I_DATA 9
-#define I_ACCUMULATOR 16
+#define I_HASARG2 16
 #define I_TWO_ARGS 17
 
 #ifdef PIKE_DEBUG
diff --git a/src/object.c b/src/object.c
index 8152f6a5d5..e0a4a44cd0 100644
--- a/src/object.c
+++ b/src/object.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: object.c,v 1.116 2000/04/20 01:49:43 mast Exp $");
+RCSID("$Id: object.c,v 1.117 2000/04/20 02:41:45 hubbe Exp $");
 #include "object.h"
 #include "dynamic_buffer.h"
 #include "interpret.h"
@@ -1136,9 +1136,9 @@ void gc_mark_object_as_referenced(struct object *o)
 	  int rtt = pike_frame->context.prog->identifiers[d].run_time_type;
 	  u=(union anything *)(pike_frame->current_storage +
 			       pike_frame->context.prog->identifiers[d].func.offset);
-#ifdef PIKE_DEBUG
+#ifdef DEBUG_MALLOC
 	  if (rtt <= MAX_REF_TYPE) debug_malloc_touch(u->refs);
-#endif /* PIKE_DEBUG */
+#endif
 	  gc_mark_short_svalue(u, rtt);
 	}
       }
@@ -1194,9 +1194,9 @@ static inline void gc_check_object(struct object *o)
 	  int rtt = pike_frame->context.prog->identifiers[d].run_time_type;
 	  u=(union anything *)(pike_frame->current_storage +
 			       pike_frame->context.prog->identifiers[d].func.offset);
-#ifdef PIKE_DEBUG
+#ifdef DEBUG_MALLOC
 	  if (rtt <= MAX_REF_TYPE) debug_malloc_touch(u->refs);
-#endif /* PIKE_DEBUG */
+#endif
 	  debug_gc_check_short_svalue(u, rtt, T_OBJECT, debug_malloc_pass(o));
 	}
       }
diff --git a/src/opcodes.c b/src/opcodes.c
index 88067166e9..a933be50a2 100644
--- a/src/opcodes.c
+++ b/src/opcodes.c
@@ -26,7 +26,7 @@
 #include "bignum.h"
 #include "operators.h"
 
-RCSID("$Id: opcodes.c,v 1.73 2000/04/01 18:59:51 grubba Exp $");
+RCSID("$Id: opcodes.c,v 1.74 2000/04/20 02:41:45 hubbe Exp $");
 
 void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind)
 {
@@ -166,8 +166,11 @@ void o_cast(struct pike_string *type, INT32 run_time_type)
 	switch(sp[-1].type)
 	{
 	  case T_ARRAY:
+	  {
+	    extern void f_mkmultiset(INT32);
 	    f_mkmultiset(1);
 	    break;
+	  }
 
 	  default:
 	    error("Cannot cast %s to multiset.\n",get_name_of_type(sp[-1].type));
diff --git a/src/operators.c b/src/operators.c
index b1506a9a03..59b9226af8 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -6,7 +6,7 @@
 /**/
 #include "global.h"
 #include <math.h>
-RCSID("$Id: operators.c,v 1.90 2000/04/12 16:55:56 grubba Exp $");
+RCSID("$Id: operators.c,v 1.91 2000/04/20 02:41:45 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "multiset.h"
@@ -436,7 +436,7 @@ static int generate_sum(node *n)
 
   case 2:
     do_docode(CDR(n),DO_NOT_COPY);
-    emit2(F_ADD);
+    emit0(F_ADD);
     return 1;
 
   default:
@@ -581,17 +581,17 @@ static int generate_comparison(node *n)
       fatal("Count args was wrong in generate_comparison.\n");
 
     if(CAR(n)->u.sval.u.efun->function == f_eq)
-      emit2(F_EQ);
+      emit0(F_EQ);
     else if(CAR(n)->u.sval.u.efun->function == f_ne)
-      emit2(F_NE);
+      emit0(F_NE);
     else if(CAR(n)->u.sval.u.efun->function == f_lt)
-      emit2(F_LT);
+      emit0(F_LT);
     else if(CAR(n)->u.sval.u.efun->function == f_le)
-      emit2(F_LE);
+      emit0(F_LE);
     else if(CAR(n)->u.sval.u.efun->function == f_gt)
-      emit2(F_GT);
+      emit0(F_GT);
     else if(CAR(n)->u.sval.u.efun->function == f_ge)
-      emit2(F_GE);
+      emit0(F_GE);
     else
       fatal("Couldn't generate comparison!\n");
     return 1;
@@ -814,12 +814,12 @@ static int generate_minus(node *n)
   {
   case 1:
     do_docode(CDR(n),DO_NOT_COPY);
-    emit2(F_NEGATE);
+    emit0(F_NEGATE);
     return 1;
 
   case 2:
     do_docode(CDR(n),DO_NOT_COPY);
-    emit2(F_SUBTRACT);
+    emit0(F_SUBTRACT);
     return 1;
   }
   return 0;
@@ -1118,7 +1118,7 @@ static int generate_and(node *n)
 
   case 2:
     do_docode(CDR(n),0);
-    emit2(F_AND);
+    emit0(F_AND);
     return 1;
 
   default:
@@ -1292,7 +1292,7 @@ static int generate_or(node *n)
 
   case 2:
     do_docode(CDR(n),0);
-    emit2(F_OR);
+    emit0(F_OR);
     return 1;
 
   default:
@@ -1471,7 +1471,7 @@ static int generate_xor(node *n)
 
   case 2:
     do_docode(CDR(n),0);
-    emit2(F_XOR);
+    emit0(F_XOR);
     return 1;
 
   default:
@@ -1514,7 +1514,7 @@ static int generate_lsh(node *n)
   if(count_args(CDR(n))==2)
   {
     do_docode(CDR(n),DO_NOT_COPY);
-    emit2(F_LSH);
+    emit0(F_LSH);
     return 1;
   }
   return 0;
@@ -1559,7 +1559,7 @@ static int generate_rsh(node *n)
   if(count_args(CDR(n))==2)
   {
     do_docode(CDR(n),DO_NOT_COPY);
-    emit2(F_RSH);
+    emit0(F_RSH);
     return 1;
   }
   return 0;
@@ -1695,7 +1695,7 @@ static int generate_multiply(node *n)
 
   case 2:
     do_docode(CDR(n),0);
-    emit2(F_MULTIPLY);
+    emit0(F_MULTIPLY);
     return 1;
 
   default:
@@ -1987,7 +1987,7 @@ static int generate_divide(node *n)
   if(count_args(CDR(n))==2)
   {
     do_docode(CDR(n),DO_NOT_COPY);
-    emit2(F_DIVIDE);
+    emit0(F_DIVIDE);
     return 1;
   }
   return 0;
@@ -2110,7 +2110,7 @@ static int generate_mod(node *n)
   if(count_args(CDR(n))==2)
   {
     do_docode(CDR(n),DO_NOT_COPY);
-    emit2(F_MOD);
+    emit0(F_MOD);
     return 1;
   }
   return 0;
@@ -2157,7 +2157,7 @@ static int generate_not(node *n)
   if(count_args(CDR(n))==1)
   {
     do_docode(CDR(n),DO_NOT_COPY);
-    emit2(F_NOT);
+    emit0(F_NOT);
     return 1;
   }
   return 0;
@@ -2249,7 +2249,7 @@ static int generate_compl(node *n)
   if(count_args(CDR(n))==1)
   {
     do_docode(CDR(n),DO_NOT_COPY);
-    emit2(F_COMPL);
+    emit0(F_COMPL);
     return 1;
   }
   return 0;
@@ -2444,16 +2444,16 @@ static int generate_sizeof(node *n)
   if(count_args(CDR(n)) != 1) return 0;
   if(do_docode(CDR(n),DO_NOT_COPY) != 1)
     fatal("Count args was wrong in sizeof().\n");
-  emit2(F_SIZEOF);
+  emit0(F_SIZEOF);
   return 1;
 }
 
 static int generate_call_function(node *n)
 {
   node **arg;
-  emit2(F_MARK);
+  emit0(F_MARK);
   do_docode(CDR(n),DO_NOT_COPY);
-  emit2(F_CALL_FUNCTION);
+  emit0(F_CALL_FUNCTION);
   return 1;
 }
 
diff --git a/src/peep.c b/src/peep.c
index 1c11c41be9..e2387e890e 100644
--- a/src/peep.c
+++ b/src/peep.c
@@ -14,7 +14,7 @@
 #include "stuff.h"
 #include "bignum.h"
 
-RCSID("$Id: peep.c,v 1.29 2000/04/18 17:23:35 hubbe Exp $");
+RCSID("$Id: peep.c,v 1.30 2000/04/20 02:41:45 hubbe Exp $");
 
 struct p_instr_s
 {
@@ -22,6 +22,7 @@ struct p_instr_s
   short line;
   struct pike_string *file;
   INT32 arg;
+  INT32 arg2;
 };
 
 typedef struct p_instr_s p_instr;
@@ -34,6 +35,28 @@ static int hasarg(int opcode)
   return instrs[opcode-F_OFFSET].flags & I_HASARG;
 }
 
+static int hasarg2(int opcode)
+{
+  return instrs[opcode-F_OFFSET].flags & I_HASARG2;
+}
+
+#ifdef PIKE_DEBUG
+static void dump_instr(p_instr *p)
+{
+  if(!p) return;
+  fprintf(stderr,"%s",get_token_name(p->opcode));
+  if(hasarg(p->opcode))
+  {
+    fprintf(stderr,"(%d",p->arg);
+    if(hasarg2(p->opcode))
+      fprintf(stderr,",%d",p->arg2);
+    fprintf(stderr,")");
+  }
+}
+#endif
+
+
+
 void init_bytecode(void)
 {
   low_reinit_buf(&instrbuf);
@@ -52,16 +75,17 @@ void exit_bytecode(void)
   toss_buffer(&instrbuf);
 }
 
-int insert_opcode(unsigned int f,
+int insert_opcode2(unsigned int f,
 		  INT32 b,
+		  INT32 c,
 		  INT32 current_line,
 		  struct pike_string *current_file)
 {
   p_instr *p;
 
 #ifdef PIKE_DEBUG
-  if(!hasarg(f) && b)
-    fatal("hasarg(%d) is wrong!\n",f);
+  if(!hasarg2(f) && c)
+    fatal("hasarg2(%d) is wrong!\n",f);
 #endif
 
   p=(p_instr *)low_make_buf_space(sizeof(p_instr), &instrbuf);
@@ -76,17 +100,31 @@ int insert_opcode(unsigned int f,
   p->line=current_line;
   copy_shared_string(p->file, current_file);
   p->arg=b;
+  p->arg2=c;
 
   return p - (p_instr *)instrbuf.s.str;
 }
 
-int insert_opcode2(int f,int current_line, struct pike_string *current_file)
+int insert_opcode1(unsigned int f,
+		  INT32 b,
+		  INT32 current_line,
+		  struct pike_string *current_file)
+{
+#ifdef PIKE_DEBUG
+  if(!hasarg(f) && b)
+    fatal("hasarg(%d) is wrong!\n",f);
+#endif
+
+  return insert_opcode2(f,b,0,current_line,current_file);
+}
+
+int insert_opcode0(int f,int current_line, struct pike_string *current_file)
 {
 #ifdef PIKE_DEBUG
   if(hasarg(f))
     fatal("hasarg(%d) is wrong!\n",f);
 #endif
-  return insert_opcode(f,0,current_line, current_file);
+  return insert_opcode1(f,0,current_line, current_file);
 }
 
 
@@ -148,6 +186,38 @@ static void ins_f_byte_with_arg(unsigned int a,unsigned INT32 b)
   add_to_program(b);
 }
 
+static void ins_f_byte_with_2_args(unsigned int a,
+				   unsigned INT32 c,
+				   unsigned INT32 b)
+{
+
+  switch(b >> 8)
+  {
+  case 0 : break;
+  case 1 : ins_f_byte(F_PREFIX2_256); break;
+  case 2 : ins_f_byte(F_PREFIX2_512); break;
+  case 3 : ins_f_byte(F_PREFIX2_768); break;
+  case 4 : ins_f_byte(F_PREFIX2_1024); break;
+  default:
+    if( b < 256*256)
+    {
+      ins_f_byte(F_PREFIX2_CHARX256);
+      add_to_program(b>>8);
+    }else if(b < 256*256*256) {
+      ins_f_byte(F_PREFIX2_WORDX256);
+      add_to_program(b>>16);
+      add_to_program(b>>8);
+    }else{
+      ins_f_byte(F_PREFIX2_24BITX256);
+      add_to_program(b>>24);
+      add_to_program(b>>16);
+      add_to_program(b>>8);
+    }
+  }
+  ins_f_byte_with_arg(a,c);
+  add_to_program(b);
+}
+
 void assemble(void)
 {
   INT32 e,d,length,max_label,tmp;
@@ -239,10 +309,9 @@ void assemble(void)
 #ifdef PIKE_DEBUG
     if((a_flag > 2 && store_linenumbers) || a_flag > 3)
     {
-      if(hasarg(c->opcode))
-	fprintf(stderr,"===%3d %4x %s(%d)\n",c->line,PC,get_token_name(c->opcode),c->arg);
-      else
-	fprintf(stderr,"===%3d %4x %s\n",c->line,PC,get_token_name(c->opcode));
+      fprintf(stderr,"===%3d %4x ",c->line,PC);
+      dump_instr(c);
+      fprintf(stderr,"\n");
     }
 #endif
 
@@ -256,10 +325,6 @@ void assemble(void)
       while(PC % c->arg) add_to_program(0);
       break;
 
-    case F_BYTE:
-      add_to_program(c->arg);
-      break;
-
     case F_DATA:
       ins_int(c->arg, (void(*)(char))add_to_program);
       break;
@@ -290,7 +355,9 @@ void assemble(void)
 	break;
 
 	case I_TWO_ARGS:
-	  /* */
+	  ins_f_byte_with_2_args(c->opcode, c->arg,c->arg2);
+	  break;
+	  
 	case I_HASARG:
 	  ins_f_byte_with_arg(c->opcode, c->arg);
 	  break;
@@ -317,7 +384,7 @@ void assemble(void)
     {
 #ifdef PIKE_DEBUG
       if(labels[e]==-1)
-	fatal("Hyperspace error: unknown jump point.\n");
+	fatal("Hyperspace error: unknown jump point %d at %d (%d).\n",e,labels[e],jumps[e]);
 #endif
       tmp=read_int(jumps[e]);
       upd_int(jumps[e], tmp2 - jumps[e]);
@@ -339,12 +406,12 @@ int remove_clear_locals=0x7fffffff;
 static int fifo_len, eye,len;
 static p_instr *instructions;
 
-int insopt(int f, INT32 b, int cl, struct pike_string *cf)
+int insopt2(int f, INT32 a, INT32 b, int cl, struct pike_string *cf)
 {
   p_instr *p;
 
 #ifdef PIKE_DEBUG
-  if(!hasarg(f) && b)
+  if(!hasarg2(f) && b)
     fatal("hasarg(%d) is wrong!\n",f);
 #endif
 
@@ -364,18 +431,29 @@ int insopt(int f, INT32 b, int cl, struct pike_string *cf)
   p->opcode=f;
   p->line=cl;
   copy_shared_string(p->file, lex.current_file);
-  p->arg=b;
+  p->arg=a;
+  p->arg2=b;
 
   return p - (p_instr *)instrbuf.s.str;
 }
 
-int insopt2(int f, int cl, struct pike_string *cf)
+int insopt1(int f, INT32 a, int cl, struct pike_string *cf)
+{
+#ifdef PIKE_DEBUG
+  if(!hasarg(f) && a)
+    fatal("hasarg(%d) is wrong!\n",f);
+#endif
+
+  return insopt2(f,a,0,cl, cf);
+}
+
+int insopt0(int f, int cl, struct pike_string *cf)
 {
 #ifdef PIKE_DEBUG
   if(hasarg(f))
     fatal("hasarg(%d) is wrong!\n",f);
 #endif
-  return insopt(f,0,cl, cf);
+  return insopt2(f,0,0,cl, cf);
 }
 
 static void debug(void)
@@ -434,6 +512,14 @@ static INLINE int argument(int offset)
   return -1;
 }
 
+static INLINE int argument2(int offset)
+{
+  p_instr *a;
+  a=instr(offset);
+  if(a) return a->arg2;
+  return -1;
+}
+
 static void advance(void)
 {
   if(fifo_len)
@@ -442,7 +528,7 @@ static void advance(void)
   }else{
     p_instr *p;
     if((p=instr(0)))
-      insert_opcode(p->opcode, p->arg, p->line, p->file);
+      insert_opcode2(p->opcode, p->arg, p->arg2, p->line, p->file);
     eye++;
   }
   debug();
@@ -473,12 +559,28 @@ static void pop_n_opcodes(int n)
   eye+=n;
 }
 
+
 static void do_optimization(int topop, ...)
 {
   va_list arglist;
   struct pike_string *cf;
   int q=-1;
   INT32 cl=instr(0)->line;
+
+#ifdef PIKE_DEBUG
+  if(a_flag>5)
+  {
+    int e;
+    fprintf(stderr,"PEEP at %d:",cl);
+    for(e=0;e<topop;e++)
+    {
+      fprintf(stderr," ");
+      dump_instr(instr(e));
+    }
+    fprintf(stderr," => ");
+  }
+#endif
+  
   copy_shared_string(cf,instr(0)->file);
   pop_n_opcodes(topop);
   va_start(arglist, topop);
@@ -493,14 +595,22 @@ static void do_optimization(int topop, ...)
       case 1:
       {
 	int i=va_arg(arglist, int);
-	insopt2(i,cl,cf);
+	insopt0(i,cl,cf);
 	continue;
       }
       case 2:
       {
 	int i=va_arg(arglist, int);
 	int j=va_arg(arglist, int);
-	insopt(i,j,cl,cf);
+	insopt1(i,j,cl,cf);
+	continue;
+      }
+      case 3:
+      {
+	int i=va_arg(arglist, int);
+	int j=va_arg(arglist, int);
+	int k=va_arg(arglist, int);
+	insopt2(i,j,k,cl,cf);
 	continue;
       }
     }
@@ -511,6 +621,20 @@ static void do_optimization(int topop, ...)
   fifo_len+=q;
   free_string(cf);
   debug();
+
+#ifdef PIKE_DEBUG
+  if(a_flag>5)
+  {
+    int e;
+    for(e=0;e<q;e++)
+    {
+      fprintf(stderr," ");
+      dump_instr(instr(e));
+    }
+    fprintf(stderr,"\n");
+  }
+#endif
+
   fifo_len+=q + 3;
 }
 
@@ -528,10 +652,9 @@ static void asm_opt(void)
     fprintf(stderr,"Optimization begins: \n");
     for(e=0;e<length;e++,c++)
     {
-      if(hasarg(c->opcode))
-	fprintf(stderr,"---%3d: %s(%d)\n",c->line,get_token_name(c->opcode),c->arg);
-      else
-	fprintf(stderr,"---%3d: %s\n",c->line,get_token_name(c->opcode));
+      fprintf(stderr,"---%3d: ",c->line);
+      dump_instr(c);
+      fprintf(stderr,"\n");
     }
   }
 #endif
@@ -551,10 +674,9 @@ static void asm_opt(void)
     fprintf(stderr,"Optimization begins: \n");
     for(e=0;e<length;e++,c++)
     {
-      if(hasarg(c->opcode))
-	fprintf(stderr,">>>%3d: %s(%d)\n",c->line,get_token_name(c->opcode),c->arg);
-      else
-	fprintf(stderr,">>>%3d: %s\n",c->line,get_token_name(c->opcode));
+      fprintf(stderr,">>>%3d: ",c->line);
+      dump_instr(c);
+      fprintf(stderr,"\n");
     }
   }
 #endif
diff --git a/src/peep.h b/src/peep.h
index 49c5f0449c..16a38c1d3f 100644
--- a/src/peep.h
+++ b/src/peep.h
@@ -1,5 +1,5 @@
 /*
- * $Id: peep.h,v 1.4 1998/03/28 15:06:27 grubba Exp $
+ * $Id: peep.h,v 1.5 2000/04/20 02:41:45 hubbe Exp $
  */
 #ifndef PEEP_H
 #define PEEP_H
@@ -11,14 +11,22 @@ extern dynamic_buffer instrbuf;
 struct p_instr_s;
 void init_bytecode(void);
 void exit_bytecode(void);
-int insert_opcode(unsigned int f,
+int insert_opcode2(unsigned int f,
 		  INT32 b,
+		  INT32 c,
 		  INT32 current_line,
 		  struct pike_string *current_file);
-int insert_opcode2(int f,int current_line, struct pike_string *current_file);
+int insert_opcode1(unsigned int f,
+		  INT32 b,
+		  INT32 current_line,
+		  struct pike_string *current_file);
+int insert_opcode0(int f,int current_line, struct pike_string *current_file);
 void update_arg(int instr,INT32 arg);
 void ins_f_byte(unsigned int b);
 void assemble(void);
+int insopt2(int f, INT32 a, INT32 b, int cl, struct pike_string *cf);
+int insopt1(int f, INT32 a, int cl, struct pike_string *cf);
+int insopt0(int f, int cl, struct pike_string *cf);
 /* Prototypes end here */
 
 #endif
diff --git a/src/peep.in b/src/peep.in
index 4f6f536401..2d031c9dd0 100644
--- a/src/peep.in
+++ b/src/peep.in
@@ -1,5 +1,5 @@
 //
-// $Id: peep.in,v 1.27 1999/11/30 07:50:18 hubbe Exp $
+// $Id: peep.in,v 1.28 2000/04/20 02:41:45 hubbe Exp $
 //
 
 NOP :
@@ -133,7 +133,7 @@ GT NOT: LE
 LE NOT: GT
 GE NOT: LT
 
-LOCAL LOCAL [$2a<256 && $3o != F_SIZEOF && $3o != F_INDEX ]: 2_LOCALS ($1a) BYTE ($2a)
+LOCAL LOCAL [$3o != F_SIZEOF && $3o != F_INDEX ]: 2_LOCALS ($1a,$2a)
 MARK LOCAL [ $3o != F_SIZEOF && $3o != F_INDEX ]: MARK_AND_LOCAL ($2a)
 MARK STRING : MARK_AND_STRING($2a)
 LOCAL SIZEOF: SIZEOF_LOCAL ($1a)
@@ -149,8 +149,8 @@ NEG_NUMBER CLEAR_STRING_SUBTYPE: NEG_NUMBER($1a)
 LOCAL INDEX: LOCAL_INDEX ($1a)
 LOCAL CLEAR_STRING_SUBTYPE INDEX: LOCAL_INDEX ($1a)
 
-LOCAL LOCAL INDEX: LOCAL_LOCAL_INDEX($2a) BYTE($1a)
-LOCAL LOCAL CLEAR_STRING_SUBTYPE INDEX: LOCAL_LOCAL_INDEX($2a) BYTE($1a)
+LOCAL LOCAL INDEX: LOCAL_LOCAL_INDEX($2a,$1a)
+LOCAL LOCAL CLEAR_STRING_SUBTYPE INDEX: LOCAL_LOCAL_INDEX($2a,$1a)
 
 CONST0 INDEX: POS_INT_INDEX (0)
 CONST_1 INDEX: NEG_INT_INDEX (1)
@@ -194,7 +194,7 @@ CALL_FUNCTION [ !(debug_options & NO_TAILRECURSION) ] RETURN : CALL_FUNCTION_AND
 CALL_LFUN [ !(debug_options & NO_TAILRECURSION) ] RETURN : CALL_LFUN_AND_RETURN($1a)
 
 LOCAL RETURN : RETURN_LOCAL($1a)
-APPLY ASSIGN_LOCAL_AND_POP : APPLY_ASSIGN_LOCAL_AND_POP($1a) BYTE($2a)
+APPLY ASSIGN_LOCAL_AND_POP : APPLY_ASSIGN_LOCAL_AND_POP($1a,$2a)
 ASSIGN_LOCAL_AND_POP INC_LOCAL_AND_POP($1a) : ADD_INT(1) ASSIGN_LOCAL_AND_POP($1a)
 ASSIGN_LOCAL_AND_POP DEC_LOCAL_AND_POP($1a) : ADD_NEG_INT(1) ASSIGN_LOCAL_AND_POP($1a)
 NUMBER ADD_INT [ !INT_TYPE_ADD_OVERFLOW($1a, $2a) ] : NUMBER($1a+$2a)
@@ -209,13 +209,13 @@ DEC_LOCAL_AND_POP LOCAL ($1a) : DEC_LOCAL ($1a)
 INC_LOCAL_AND_POP LOCAL ($1a) : INC_LOCAL ($1a)
 ASSIGN_LOCAL_AND_POP LOCAL($1a) : ASSIGN_LOCAL($1a)
 ASSIGN_GLOBAL_AND_POP GLOBAL($1a) : ASSIGN_GLOBAL($1a)
-APPLY_ASSIGN_LOCAL_AND_POP BYTE LOCAL ($2a) : APPLY_ASSIGN_LOCAL($1a) BYTE($2a)
+APPLY_ASSIGN_LOCAL_AND_POP LOCAL ($1b) : APPLY_ASSIGN_LOCAL($1a,$1b)
 
 DEC_LOCAL_AND_POP MARK_AND_LOCAL ($1a) : MARK DEC_LOCAL ($1a)
 INC_LOCAL_AND_POP MARK_AND_LOCAL ($1a) : MARK INC_LOCAL ($1a)
 ASSIGN_GLOBAL_AND_POP MARK GLOBAL($1a) : MARK_X(1) ASSIGN_GLOBAL($1a)
 ASSIGN_LOCAL_AND_POP MARK_AND_LOCAL($1a) : MARK_X(1) ASSIGN_LOCAL($1a)
-APPLY_ASSIGN_LOCAL_AND_POP BYTE MARK_AND_LOCAL ($2a) : APPLY_ASSIGN_LOCAL($1a) BYTE($2a) MARK_X(1) 
+APPLY_ASSIGN_LOCAL_AND_POP MARK_AND_LOCAL ($1b) : APPLY_ASSIGN_LOCAL($1a,$1b) MARK_X(1) 
 
 ASSIGN_LOCAL ASSIGN_LOCAL($1a) : ASSIGN_LOCAL($1a)
 
@@ -235,7 +235,7 @@ FLOAT MARK_X [$2a>0] : MARK_X($2a-1) FLOAT($1a)
 LFUN MARK_X [$2a>0] : MARK_X($2a-1) LFUN($1a)
 LTOSVAL MARK_X [$2a>0] : MARK_X($2a-1) LTOSVAL
 LOCAL_LVALUE MARK_X [$2a>1] : MARK_X($2a-2) LOCAL_LVALUE($1a)
-2_LOCALS BYTE MARK_X [$2a>0] : LOCAL($1a) MARK_X($3a-1) LOCAL($2a)
+2_LOCALS MARK_X [$2a>0] : LOCAL($1a) MARK_X($2a-1) LOCAL($1b)
 
 #define BasicBranch2(Branch,Oper,Pre,Post,Variable) \
  Variable Branch Pre Variable ($1a) : Variable ($1a) Oper ($2a) Post ; \
@@ -252,14 +252,14 @@ LOCAL_LVALUE MARK_X [$2a>1] : MARK_X($2a-2) LOCAL_LVALUE($1a)
 BasicBranch0(BRANCH_WHEN_NON_ZERO, BRANCH_AND_POP_WHEN_NON_ZERO)
 BasicBranch0(BRANCH_WHEN_ZERO, BRANCH_AND_POP_WHEN_ZERO)
 
-LOCAL ASSIGN_LOCAL_AND_POP : LOCAL_2_LOCAL($2a) BYTE($1a)
-GLOBAL ASSIGN_LOCAL_AND_POP : GLOBAL_2_LOCAL($1a) BYTE($2a)
-LOCAL ASSIGN_GLOBAL_AND_POP : LOCAL_2_GLOBAL($2a) BYTE($1a)
+LOCAL ASSIGN_LOCAL_AND_POP : LOCAL_2_LOCAL($2a,$1a)
+GLOBAL ASSIGN_LOCAL_AND_POP : GLOBAL_2_LOCAL($1a,$2a)
+LOCAL ASSIGN_GLOBAL_AND_POP : LOCAL_2_GLOBAL($2a,$1a)
 
-LOCAL ARROW : LOCAL_ARROW($2a) BYTE($1a)
-LOCAL_ARROW BYTE BRANCH_WHEN_ZERO: BRANCH_IF_NOT_LOCAL_ARROW($1a) BYTE($2a) POINTER($3a)
+LOCAL ARROW : LOCAL_ARROW($2a,$1a)
+LOCAL_ARROW BRANCH_WHEN_ZERO: BRANCH_IF_NOT_LOCAL_ARROW($1a,$1b) POINTER($2a)
 
-GLOBAL LOCAL_INDEX : GLOBAL_LOCAL_INDEX($1a) BYTE($2a)
+GLOBAL LOCAL_INDEX : GLOBAL_LOCAL_INDEX($1a,$2a)
 
 SIZEOF CONST1 BRANCH_WHEN_LT : SIZEOF BRANCH_WHEN_ZERO ($3a)
 SIZEOF_LOCAL CONST1 BRANCH_WHEN_LT : SIZEOF_LOCAL($1a) BRANCH_WHEN_ZERO ($3a)
-- 
GitLab