diff --git a/src/docode.c b/src/docode.c
index 5e1c52e3f8162c8776667a383204356c9f6e5ad3..a99b16402f7fed9264e74a5ee9879bc9108e4dbc 100644
--- a/src/docode.c
+++ b/src/docode.c
@@ -19,11 +19,11 @@
 #include "main.h"
 #include "lex.h"
 #include "builtin_efuns.h"
+#include "peep.h"
+#include "docode.h"
 
-int *break_stack=0;
-static int current_break,break_stack_size;
-int *continue_stack=0;
-static int current_continue,continue_stack_size;
+INT32 current_break=-1;
+INT32 current_continue=-1;
 
 static INT32 current_switch_case;
 static INT32 current_switch_default;
@@ -45,131 +45,35 @@ void ins_short(INT16 l,int area)
   add_to_mem_block(area, (char *)&l, sizeof(INT16));
 }
 
-static void upd_short(int offset, INT16 l)
-{
-#ifdef HANDLES_UNALIGNED_MEMORY_ACCESS
-  *((INT16 *)(areas[A_PROGRAM].s.str+offset))=l;
-#else
-  MEMCPY(areas[A_PROGRAM].s.str+offset, (char *)&l,sizeof(l));
-#endif
-}
-
-static void upd_int(int offset, INT32 tmp)
-{
-#ifdef HANDLES_UNALIGNED_MEMORY_ACCESS
-  *((int *)(areas[A_PROGRAM].s.str+offset))=tmp;
-#else
-  MEMCPY(areas[A_PROGRAM].s.str+offset, (char *)&tmp,sizeof(tmp));
-#endif
-}
-
 /*
  * Store an INT32.
  */
-void ins_long(INT32 l,int area)
+void ins_int(INT32 l,int area)
 {
   add_to_mem_block(area, (char *)&l+0, sizeof(INT32));
 }
 
-int store_linenumbers=1;
-
-static void low_ins_f_byte(unsigned int b)
+void upd_int(int offset, INT32 tmp)
 {
-  if(store_linenumbers) store_linenumber();
-
-#if defined(LASDEBUG)
-  if(lasdebug>1)
-    if(store_linenumbers)
-      fprintf(stderr,"Inserting f_byte %s (%d) at %ld\n",
-	      get_instruction_name(b), b,
-	      (long)PC);
-#endif
-  b-=F_OFFSET;
-#ifdef OPCPROF
-  if(store_linenumbers) add_compiled(b);
-#endif
-  if(b>255)
-  {
-    switch(b >> 8)
-    {
-    case 1: low_ins_f_byte(F_ADD_256); break;
-    case 2: low_ins_f_byte(F_ADD_512); break;
-    case 3: low_ins_f_byte(F_ADD_768); break;
-    case 4: low_ins_f_byte(F_ADD_1024); break;
-    default:
-      low_ins_f_byte(F_ADD_256X);
-      ins_byte(b/256,A_PROGRAM);
-    }
-    b&=255;
-  }
-  ins_byte((unsigned char)b,A_PROGRAM);
-}
-
-void ins_f_byte(unsigned int b)
-{
-#ifdef DEBUG
-  if(a_flag>2)
-    fprintf(stderr,">%6lx: %s\n",(long)PC,get_f_name(b));
+#ifdef HANDLES_UNALIGNED_MEMORY_ACCESS
+  *((int *)(areas[A_PROGRAM].s.str+offset))=tmp;
+#else
+  MEMCPY(areas[A_PROGRAM].s.str+offset, (char *)&tmp,sizeof(tmp));
 #endif
-  low_ins_f_byte(b);
 }
 
-static void ins_f_byte_with_numerical_arg(unsigned int a,unsigned int b)
+INT32 read_int(int offset)
 {
-  switch(b >> 8)
-  {
-  case 0 : break;
-  case 1 : low_ins_f_byte(F_PREFIX_256); break;
-  case 2 : low_ins_f_byte(F_PREFIX_512); break;
-  case 3 : low_ins_f_byte(F_PREFIX_768); break;
-  case 4 : low_ins_f_byte(F_PREFIX_1024); break;
-  default:
-    if( b < 256*256)
-    {
-      low_ins_f_byte(F_PREFIX_CHARX256);
-      ins_byte(b>>8, A_PROGRAM);
-    }else if(b < 256*256*256) {
-      low_ins_f_byte(F_PREFIX_WORDX256);
-      ins_byte(b >> 16, A_PROGRAM);
-      ins_byte(b >> 8, A_PROGRAM);
-    }else{
-      low_ins_f_byte(F_PREFIX_24BITX256);
-      ins_byte(b >> 24, A_PROGRAM);
-      ins_byte(b >> 16, A_PROGRAM);
-      ins_byte(b >> 8, A_PROGRAM);
-    }
-  }
-  ins_f_byte(a);
-#ifdef DEBUG
-  if(a_flag>2)
-    fprintf(stderr,">%6lx: argument = %u\n",(long)PC,b);
+  INT32 tmp;
+#ifdef HANDLES_UNALIGNED_MEMORY_ACCESS
+  tmp=*((int *)(areas[A_PROGRAM].s.str+offset));
+#else
+  MEMCPY((char *)&tmp, areas[A_PROGRAM].s.str+offset,sizeof(tmp));
 #endif
-  ins_byte(b, A_PROGRAM);
-}
-
-
-static void ins_int(int i)
-{
-  switch(i)
-  {
-  case 0: ins_f_byte(F_CONST0); break;
-  case 1: ins_f_byte(F_CONST1); break;
-  case -1: ins_f_byte(F_CONST_1); break;
-  default:
-    if(i<0)
-    {
-      ins_f_byte_with_numerical_arg(F_NEG_NUMBER,-i);
-    }else{
-      ins_f_byte_with_numerical_arg(F_NUMBER,i);
-    }
-  }
+  return tmp;
 }
 
-static void ins_float(FLOAT_TYPE f)
-{
-  ins_f_byte(F_FLOAT);
-  add_to_mem_block(A_PROGRAM,(char *)&f,sizeof(FLOAT_TYPE));
-}
+int store_linenumbers=1;
 
 /*
  * A mechanism to remember addresses on a stack. The size of the stack is
@@ -212,173 +116,16 @@ INT32 pop_address()
   return comp_stack[--comp_stackp];
 }
 
-static void do_pop(int nr)
-{
-  if(!nr) return;
-  if(nr==1)
-  {
-    ins_f_byte(F_POP_VALUE);
-  }else if(nr<256){
-    ins_f_byte(F_POP_N_ELEMS);
-    ins_byte(nr,A_PROGRAM);
-  }else{
-    ins_f_byte(F_POP_N_ELEMS);
-    ins_byte(255,A_PROGRAM);
-    do_pop(nr-255);
-  }
-}
-
-/* routines to optimize jumps */
-
-#define JUMP_CONDITIONAL 1
-#define JUMP_UNSET 2
-
-struct jump
-{
-  INT32 relative;
-  INT32 whereto;
-  INT32 wherefrom;
-  INT32 address;
-  unsigned char flags;
-  short token;
-};
-
-static int jump_ptr=0, max_jumps=0;
-static struct jump jumps[256];
-
-static void low_set_branch(INT32 address,INT32 whereto,INT32 relative)
-{
-  int j,e;
-
-  if(address<0) return;
-  j=jump_ptr;
-  e=max_jumps;
-  while(e>=0)
-  {
-    if(jumps[j].address==address && (jumps[j].flags & JUMP_UNSET))
-      break;
-    if(j) j--; else j=max_jumps;
-    e--;
-  }
-  if(e<0) j=-1; /* not found */
-    
-  for(e=0;e<=max_jumps;e++)
-  {
-    if(jumps[e].flags & JUMP_UNSET) continue;
-    if(jumps[e].flags & JUMP_CONDITIONAL) continue;
-    if(jumps[e].wherefrom!=whereto) continue;
-#if defined(LASDEBUG)
-    if(lasdebug>1) printf("Optimized Jump to a jump\n");
-#endif
-    whereto=jumps[e].whereto;
-    break;
-  }
-  
-  if(j>=0)
-  {
-    if(!(jumps[j].flags & JUMP_CONDITIONAL))
-    {
-      for(e=0;e<=max_jumps;e++)
-      {
-	if(jumps[e].flags & JUMP_UNSET) continue;
-	if(jumps[e].whereto==jumps[j].wherefrom)
-	{
-	  upd_int(jumps[e].address,whereto - jumps[e].relative);
-	  jumps[e].whereto=whereto;
-#if defined(LASDEBUG)
-	  if(lasdebug>1) printf("Optimized Jump to a jump\n");
-#endif
-	}
-      }
-    }
-    jumps[j].relative=relative;
-    jumps[j].whereto=whereto;
-    jumps[j].flags&=~JUMP_UNSET;
-  }
-  upd_int(address,whereto - relative);
-}
-
-static void set_branch(INT32 address,INT32 whereto)
-{
-  low_set_branch(address,whereto,address);
-}
 
-static INT32 do_jump(int token,INT32 whereto)
-{
-  jump_ptr=(jump_ptr+1)%NELEM(jumps);
-  if(jump_ptr>max_jumps) max_jumps=jump_ptr;
+static int label_no=0;
 
-  jumps[jump_ptr].flags=JUMP_UNSET;
-  jumps[jump_ptr].whereto=-1;
-  jumps[jump_ptr].token=token;
+static int alloc_label() { return ++label_no; }
 
-  if(token!=F_BRANCH)
-    jumps[jump_ptr].flags|=JUMP_CONDITIONAL;
-
-  if(token>=0)
-  {
-    jumps[jump_ptr].wherefrom=PC;
-    ins_f_byte(token);
-  }else{
-    jumps[jump_ptr].wherefrom=-1;
-  }
-  jumps[jump_ptr].relative=PC;
-  jumps[jump_ptr].address=PC;
-  ins_long(0, A_PROGRAM);
-  if(whereto!=-1) set_branch(jumps[jump_ptr].address, whereto);
-  return jumps[jump_ptr].address;
-}
-
-static void clean_jumptable() { max_jumps=jump_ptr=-1; }
-
-struct jump_list
+static int do_jump(int token,INT32 lbl)
 {
-  int *stack;
-  int current;
-  int size;
-};
-
-static void push_break_stack(struct jump_list *x)
-{
-  x->stack=break_stack;
-  x->current=current_break;
-  x->size=break_stack_size;
-  break_stack_size=10;
-  break_stack=(int *)xalloc(sizeof(int)*break_stack_size);
-  current_break=0;
-}
-
-static void pop_break_stack(struct jump_list *x,int jump)
-{
-  for(current_break--;current_break>=0;current_break--)
-    set_branch(break_stack[current_break],jump);
-
-  free((char *)break_stack);
-  
-  break_stack_size=x->size;
-  current_break=x->current;
-  break_stack=x->stack;
-}
-
-static void push_continue_stack(struct jump_list *x)
-{
-  x->stack=continue_stack;
-  x->current=current_continue;
-  x->size=continue_stack_size;
-  continue_stack_size=10;
-  continue_stack=(int *)xalloc(sizeof(int)*continue_stack_size);
-  current_continue=0;
-}
-
-static void pop_continue_stack(struct jump_list *x,int jump)
-{
-  for(current_continue--;current_continue>=0;current_continue--)
-    set_branch(continue_stack[current_continue],jump);
-
-  free((char *)continue_stack);
-  continue_stack_size=x->size;
-  current_continue=x->current;
-  continue_stack=x->stack;
+  if(lbl==-1) lbl=alloc_label();
+  emit(token, lbl);
+  return lbl;
 }
 
 static int do_docode2(node *n,int flags);
@@ -387,6 +134,17 @@ static int do_docode2(node *n,int flags);
 #define DO_NOT_COPY 2
 #define DO_POP 4
 
+#define ins_label(L) do_jump(F_LABEL, L)
+
+static 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;
+  }
+}
 #define DO_CODE_BLOCK(N) do_pop(do_docode(N,DO_NOT_COPY | DO_POP))
 
 int do_docode(node *n,INT16 flags)
@@ -402,12 +160,6 @@ int do_docode(node *n,INT16 flags)
 }
 
 
-int docode(node *n)
-{
-  clean_jumptable();
-  return do_docode(n,0);
-}
-
 static INT32 do_jump_when_zero(node *n,int j);
 
 static int do_jump_when_non_zero(node *n,int j)
@@ -488,7 +240,7 @@ static int do_docode2(node *n,int flags)
     {
     default:
       yyerror("Illegal lvalue.");
-      ins_int(0);
+      emit(F_NUMBER,0);
       return 1;
 
     case F_LVALUE_LIST:
@@ -509,7 +261,7 @@ static int do_docode2(node *n,int flags)
     {
       fatal("Internal compiler error, Yikes!\n");
     }
-    ins_f_byte(F_PUSH_ARRAY);
+    emit2(F_PUSH_ARRAY);
     return -0x7ffffff;
 
   case '?':
@@ -518,7 +270,7 @@ static int do_docode2(node *n,int flags)
     {
       tmp1=do_jump_when_zero(CAR(n), -1);
       DO_CODE_BLOCK(CADR(n));
-      set_branch(tmp1, PC);
+      emit(F_LABEL, tmp1);
       return 0;
     }
 
@@ -526,7 +278,7 @@ static int do_docode2(node *n,int flags)
     {
       tmp1=do_jump_when_non_zero(CAR(n), -1);
       DO_CODE_BLOCK(CDDR(n));
-      set_branch(tmp1, PC);
+      emit(F_LABEL,tmp1);
       return 0;
     }
 
@@ -545,12 +297,12 @@ static int do_docode2(node *n,int flags)
     do_pop(tmp3 - tmp1);
 
     tmp3=do_jump(F_BRANCH,-1);
-    set_branch(tmp2, PC);
+    emit(F_LABEL, tmp2);
 
     tmp2=do_docode(CDDR(n), flags);
     if(tmp2 < tmp1) fatal("Count arguments was wrong.\n");
     do_pop(tmp2 - tmp1);
-    set_branch(tmp3, PC);
+    emit(F_LABEL, tmp3);
     return tmp1;
   }
       
@@ -574,9 +326,9 @@ static int do_docode2(node *n,int flags)
     {
       if(do_docode(CDR(n), 0)!=1)
 	fatal("Internal compiler error, shit happens\n");
-      ins_f_byte(F_LTOSVAL2);
+      emit2(F_LTOSVAL2);
     }else{
-      ins_f_byte(F_LTOSVAL);
+      emit2(F_LTOSVAL);
       if(do_docode(CDR(n), 0)!=1)
 	fatal("Internal compiler error, shit happens (again)\n");
     }
@@ -584,24 +336,24 @@ static int do_docode2(node *n,int flags)
 
     switch(n->token)
     {
-    case F_ADD_EQ: ins_f_byte(F_ADD); break;
-    case F_AND_EQ: ins_f_byte(F_AND); break;
-    case F_OR_EQ:  ins_f_byte(F_OR);  break;
-    case F_XOR_EQ: ins_f_byte(F_XOR); break;
-    case F_LSH_EQ: ins_f_byte(F_LSH); break;
-    case F_RSH_EQ: ins_f_byte(F_RSH); break;
-    case F_SUB_EQ: ins_f_byte(F_SUBTRACT); break;
-    case F_MULT_EQ:ins_f_byte(F_MULTIPLY);break;
-    case F_MOD_EQ: ins_f_byte(F_MOD); break;
-    case F_DIV_EQ: ins_f_byte(F_DIVIDE); break;
+    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;
     }
 
     if(flags & DO_POP)
     {
-      ins_f_byte(F_ASSIGN_AND_POP);
+      emit2(F_ASSIGN_AND_POP);
       return 0;
     }else{
-      ins_f_byte(F_ASSIGN);
+      emit2(F_ASSIGN);
       return 1;
     }
 
@@ -625,16 +377,16 @@ static int do_docode2(node *n,int flags)
 	{
 	  if(do_docode(CDAR(n),DO_NOT_COPY)!=1)
 	    fatal("Infernal compiler error (dumpar core |ver hela mattan).\n");
-	  ins_f_byte(F_LTOSVAL2);
+	  emit2(F_LTOSVAL2);
 	}else{
-	  ins_f_byte(F_LTOSVAL);
+	  emit2(F_LTOSVAL);
 	  if(do_docode(CDAR(n),DO_NOT_COPY)!=1)
 	    fatal("Infernal compiler error (dumpar core).\n");
 	}
 
-	ins_f_byte(CAR(n)->token);
+	emit2(CAR(n)->token);
 
-	ins_f_byte(n->token);
+	emit2(n->token);
 	return n->token==F_ASSIGN;
       }
 
@@ -648,17 +400,17 @@ static int do_docode2(node *n,int flags)
       switch(CDR(n)->token)
       {
       case F_LOCAL:
-	ins_f_byte(flags & DO_POP ? F_ASSIGN_LOCAL_AND_POP:F_ASSIGN_LOCAL);
-	ins_byte(CDR(n)->u.number,A_PROGRAM);
+	emit(flags & DO_POP ? F_ASSIGN_LOCAL_AND_POP:F_ASSIGN_LOCAL,
+	     CDR(n)->u.number );
 	break;
 
       case F_GLOBAL:
-	ins_f_byte(flags & DO_POP ? F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL);
-	ins_byte(CDR(n)->u.number,A_PROGRAM);
+	emit(flags & DO_POP ? F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL,
+	     CDR(n)->u.number);
 	break;
 
       default:
-	ins_f_byte(flags & DO_POP ? F_ASSIGN_AND_POP:F_ASSIGN);
+	emit2(flags & DO_POP ? F_ASSIGN_AND_POP:F_ASSIGN);
 	break;
       }
       return flags & DO_POP ? 0 : 1;
@@ -671,7 +423,7 @@ static int do_docode2(node *n,int flags)
     tmp1=do_jump(n->token,-1);
     if(do_docode(CDR(n),0)!=1)
       fatal("Compiler internal error.\n");
-    set_branch(tmp1,PC);
+    emit(F_LABEL,tmp1);
     return 1;
 
   case F_EQ:
@@ -699,7 +451,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.\n");
-    ins_f_byte(n->token);
+    emit2(n->token);
     return tmp1;
 
   case F_INC:
@@ -712,10 +464,10 @@ static int do_docode2(node *n,int flags)
 
     if(flags & DO_POP)
     {
-      ins_f_byte(F_INC_AND_POP);
+      emit2(F_INC_AND_POP);
       return 0;
     }else{
-      ins_f_byte(n->token);
+      emit2(n->token);
       return 1;
     }
 
@@ -728,36 +480,40 @@ static int do_docode2(node *n,int flags)
 #endif
     if(flags & DO_POP)
     {
-      ins_f_byte(F_DEC_AND_POP);
+      emit2(F_DEC_AND_POP);
       return 0;
     }else{
-      ins_f_byte(n->token);
+      emit2(n->token);
       return 1;
     }
 
   case F_FOR:
   {
-    struct jump_list brk,cnt;
     INT32 *prev_switch_jumptable = current_switch_jumptable;
+    INT32 break_save = current_break;
+    INT32 continue_save = current_continue;
+    
     current_switch_jumptable=0;
+    current_break=alloc_label();
+    current_continue=alloc_label();
 
-    push_break_stack(&brk);
-    push_continue_stack(&cnt);
     if(CDR(n))
     {
       tmp1=do_jump(F_BRANCH,-1);
-      tmp2=PC;
+      tmp2=ins_label(-1);
       if(CDR(n)) DO_CODE_BLOCK(CADR(n));
-      pop_continue_stack(&cnt,PC);
+      ins_label(current_continue);
       if(CDR(n)) DO_CODE_BLOCK(CDDR(n));
-      set_branch(tmp1,PC);
+      emit(F_LABEL,tmp1);
     }else{
       tmp2=PC;
     }
     do_jump_when_non_zero(CAR(n),tmp2);
-    pop_break_stack(&brk,PC);
+    ins_label(current_break);
 
     current_switch_jumptable = prev_switch_jumptable;
+    current_break=break_save;
+    current_continue=continue_save;
     return 0;
   }
 
@@ -766,23 +522,27 @@ static int do_docode2(node *n,int flags)
 
   case F_FOREACH:
   {
-    struct jump_list cnt,brk;
     INT32 *prev_switch_jumptable = current_switch_jumptable;
+    INT32 break_save = current_break;
+    INT32 continue_save = current_continue;
+
     current_switch_jumptable=0;
+    current_break=alloc_label();
+    current_continue=alloc_label();
 
     tmp2=do_docode(CAR(n),DO_NOT_COPY);
-    ins_f_byte(F_CONST0);
+    emit2(F_CONST0);
     tmp3=do_jump(F_BRANCH,-1);
-    tmp1=PC;
-    push_break_stack(&brk);
-    push_continue_stack(&cnt);
+    tmp1=ins_label(-1);
     DO_CODE_BLOCK(CDR(n));
-    pop_continue_stack(&cnt,PC);
-    set_branch(tmp3,PC);
+    ins_label(current_continue);
+    emit(F_LABEL,tmp3);
     do_jump(n->token,tmp1);
-    pop_break_stack(&brk,PC);
+    ins_label(current_break);
 
     current_switch_jumptable = prev_switch_jumptable;
+    current_break=break_save;
+    current_continue=continue_save;
     return 0;
   }
 
@@ -791,40 +551,49 @@ static int do_docode2(node *n,int flags)
   case F_INC_LOOP:
   case F_DEC_LOOP:
   {
-    struct jump_list cnt,brk;
     INT32 *prev_switch_jumptable = current_switch_jumptable;
+    INT32 break_save = current_break;
+    INT32 continue_save = current_continue;
+
     current_switch_jumptable=0;
+    current_break=alloc_label();
+    current_continue=alloc_label();
 
     tmp2=do_docode(CAR(n),0);
     tmp3=do_jump(F_BRANCH,-1);
-    tmp1=PC;
-    push_break_stack(&brk);
-    push_continue_stack(&cnt);
+    tmp1=ins_label(-1);
+
     DO_CODE_BLOCK(CDR(n));
-    pop_continue_stack(&cnt,PC);
-    set_branch(tmp3,PC);
+    ins_label(current_continue);
+    emit(F_LABEL,tmp3);
     do_jump(n->token,tmp1);
-    pop_break_stack(&brk,PC);
+    ins_label(current_break);
 
     current_switch_jumptable = prev_switch_jumptable;
+    current_break=break_save;
+    current_continue=continue_save;
     return 0;
   }
 
   case F_DO:
   {
-    struct jump_list cnt,brk;
     INT32 *prev_switch_jumptable = current_switch_jumptable;
+    INT32 break_save = current_break;
+    INT32 continue_save = current_continue;
+
     current_switch_jumptable=0;
+    current_break=alloc_label();
+    current_continue=alloc_label();
 
-    tmp2=PC;
-    push_break_stack(&brk);
-    push_continue_stack(&cnt);
+    tmp2=ins_label(-1);
     DO_CODE_BLOCK(CAR(n));
-    pop_continue_stack(&cnt,PC);
+    ins_label(current_continue);
     do_jump_when_non_zero(CDR(n),tmp2);
-    pop_break_stack(&brk,PC);
+    ins_label(current_break);
 
     current_switch_jumptable = prev_switch_jumptable;
+    current_break=break_save;
+    current_continue=continue_save;
     return 0;
   }
 
@@ -836,12 +605,12 @@ static int do_docode2(node *n,int flags)
     }
 
     tmp1=do_docode(CAR(n),0);
-    if(!tmp1) { ins_f_byte(F_CONST0); tmp1=1; }
+    if(!tmp1) { emit2(F_CONST0); tmp1=1; }
     if(tmp1>1) do_pop(tmp1-1);
 
     tmp1=store_prog_string(n->type);
-    ins_f_byte_with_numerical_arg(F_STRING,tmp1);
-    ins_f_byte(F_CAST);
+    emit(F_STRING,tmp1);
+    emit2(F_CAST);
     return 1;
 
   case F_APPLY:
@@ -854,39 +623,39 @@ static int do_docode2(node *n,int flags)
 	  if(!CAR(n)->u.sval.u.efun->docode || 
 	     !CAR(n)->u.sval.u.efun->docode(n))
 	  {
-	    ins_f_byte(F_MARK);
+	    emit2(F_MARK);
 	    do_docode(CDR(n),0);
 	    tmp1=store_constant(& CAR(n)->u.sval,
 				!(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND));
-	    ins_f_byte(F_MAX_OPCODE + tmp1);
+	    emit(F_APPLY,tmp1);
 	  }
 	  if(n->type == void_type_string) return 0;
 	  return 1;
 	}else{
 	  if(CAR(n)->u.sval.u.object == &fake_object)
 	  {
-	    ins_f_byte(F_MARK);
+	    emit2(F_MARK);
 	    do_docode(CDR(n),0);
-	    ins_f_byte_with_numerical_arg(F_CALL_LFUN, CAR(n)->u.sval.subtype);
+	    emit(F_CALL_LFUN, CAR(n)->u.sval.subtype);
 	    return 1;
 	  }
        	}
       }
 
-      ins_f_byte(F_MARK);
+      emit2(F_MARK);
       do_docode(CDR(n),0);
       tmp1=store_constant(& CAR(n)->u.sval,
 			  !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND));
-      ins_f_byte(F_MAX_OPCODE + tmp1);
+      emit(F_APPLY,tmp1);
       
       return 1;
     }
     else if(CAR(n)->token == F_IDENTIFIER &&
 	    ID_FROM_INT(& fake_program, CAR(n)->u.number)->flags & IDENTIFIER_FUNCTION)
     {
-      ins_f_byte(F_MARK);
+      emit2(F_MARK);
       do_docode(CDR(n),0);
-      ins_f_byte_with_numerical_arg(F_CALL_LFUN, CAR(n)->u.number);
+      emit(F_CALL_LFUN, CAR(n)->u.number);
       return 1;
     }
     else
@@ -894,7 +663,7 @@ static int do_docode2(node *n,int flags)
       struct lpc_string *tmp;
       struct efun *fun;
 
-      ins_f_byte(F_MARK);
+      emit2(F_MARK);
       tmp=make_shared_string("call_function");
       if(!tmp) yyerror("No call_function efun.");
       fun=lookup_efun(tmp);
@@ -904,7 +673,7 @@ static int do_docode2(node *n,int flags)
       do_docode(CAR(n),0);
       do_docode(CDR(n),0);
       tmp1=store_constant(& fun->function, 1);
-      ins_f_byte(tmp1 + F_MAX_OPCODE);
+      emit(F_APPLY, tmp1);
       return 1;
     }
 
@@ -929,27 +698,24 @@ static int do_docode2(node *n,int flags)
 
   case F_SWITCH:
   {
-    struct jump_list brk;
     INT32 e,cases,*order;
     INT32 *jumptable;
     INT32 prev_switch_values_on_stack = current_switch_values_on_stack;
     INT32 prev_switch_case = current_switch_case;
     INT32 prev_switch_default = current_switch_default;
     INT32 *prev_switch_jumptable = current_switch_jumptable;
+    INT32 break_save = current_break;
 
     if(do_docode(CAR(n),0)!=1)
       fatal("Internal compiler error, time to panic\n");
 
-    push_break_stack(&brk);
+    current_break=alloc_label();
 
     cases=count_cases(CDR(n));
 
-    ins_f_byte(F_SWITCH);
-    tmp1=PC;
-    ins_short(0, A_PROGRAM);
-    while(PC != (unsigned INT32)MY_ALIGN(PC))
-      ins_byte(0, A_PROGRAM);
-    tmp2=PC;
+    tmp1=emit(F_SWITCH,0);
+    emit(F_ALIGN,sizeof(INT32));
+
     current_switch_values_on_stack=0;
     current_switch_case=0;
     current_switch_default=-1;
@@ -958,29 +724,30 @@ static int do_docode2(node *n,int flags)
 
     for(e=0; e<cases*2+1; e++)
     {
-      jumptable[e]=do_jump(-1,-1);
+      jumptable[e]=emit(F_POINTER, 0);
       current_switch_jumptable[e]=-1;
     }
 
     current_switch_jumptable[current_switch_case++]=-1;
 
     DO_CODE_BLOCK(CDR(n));
-
+    
     f_aggregate(cases);
-    sp[-1].u.array=compact_array(sp[-1].u.array);
     order=get_switch_order(sp[-1].u.array);
-    
+
+    /* Check for cases inside a range */
     for(e=0; e<cases-1; e++)
     {
-      if(current_switch_jumptable[order[e]*2+2] != -1)
+      if(current_switch_jumptable[ order[e]*2+2 ] != -1)
       {
-	if(current_switch_jumptable[order[e]*2+2] !=
-	   current_switch_jumptable[order[e+1]*2+1])
+	if(current_switch_jumptable[ order[e]*2+2 ] !=
+	   current_switch_jumptable[ order[e+1]*2+1 ])
 	  yyerror("Case inside range.");
       }
     }
 
-    if(current_switch_default < 0) current_switch_default = PC;
+    if(current_switch_default < 0)
+      current_switch_default = ins_label(-1);
 
     for(e=0;e<cases*2+1;e++)
       if(current_switch_jumptable[e]==-1)
@@ -992,10 +759,9 @@ static int do_docode2(node *n,int flags)
     free((char *)order);
 
     for(e=0; e<cases*2+1; e++)
-      low_set_branch(jumptable[e], current_switch_jumptable[e],tmp2);
+      update_arg(jumptable[e], current_switch_jumptable[e]);
 
-    e=store_constant(sp-1,1);
-    upd_short(tmp1,e);
+    update_arg(tmp1, store_constant(sp-1,1));
 
     pop_stack();
     free((char *)jumptable);
@@ -1006,8 +772,9 @@ static int do_docode2(node *n,int flags)
     current_switch_case = prev_switch_case;
     current_switch_values_on_stack = prev_switch_values_on_stack ;
 
-    pop_break_stack(&brk,PC);
+    emit(F_LABEL, current_break);
 
+    current_break=break_save;
     return 0;
   }
 
@@ -1032,11 +799,17 @@ static int do_docode2(node *n,int flags)
 	if(is_equal(sp-tmp1, sp-1))
 	  yyerror("Duplicate case.");
 
-      current_switch_jumptable[current_switch_case++]=PC;
+      current_switch_jumptable[current_switch_case++]=ins_label(-1);
 
       if(CDR(n))
       {
-	current_switch_jumptable[current_switch_case++]=PC;
+	if(!is_const(CDR(n)))
+	  yyerror("Case label isn't constant.");
+
+	current_switch_jumptable[current_switch_case+1]=
+	  current_switch_jumptable[current_switch_case]=
+	    current_switch_jumptable[current_switch_case-1];
+	current_switch_case+=2;
 	tmp1=eval_low(CDR(n));
 	if(tmp1<1)
 	{
@@ -1049,7 +822,6 @@ static int do_docode2(node *n,int flags)
 	for(tmp1=current_switch_values_on_stack; tmp1 > 1; tmp1--)
 	  if(is_equal(sp-tmp1, sp-1))
 	    yyerror("Duplicate case.");
-	current_switch_jumptable[current_switch_case++]=PC;
       }
       current_switch_jumptable[current_switch_case++]=-1;
     }
@@ -1063,74 +835,58 @@ static int do_docode2(node *n,int flags)
     }else if(current_switch_default!=-1){
       yyerror("Duplicate switch default.");
     }else{
-      current_switch_default = PC;
+      current_switch_default = ins_label(-1);
     }
     return 0;
 
   case F_BREAK:
-    if(!break_stack)
+    if(current_break == -1)
     {
       yyerror("Break outside loop or switch.");
     }else{
-      if(current_break>=break_stack_size)
-      {
-	break_stack_size*=2;
-	break_stack=(int *)realloc((char *)break_stack,
-				   sizeof(int)*break_stack_size);
-	if(!break_stack)
-	  fatal("Out of memory.\n");
-      }
-      break_stack[current_break++]=do_jump(F_BRANCH,-1);
+      do_jump(F_BRANCH, current_break);
     }
     return 0;
 
   case F_CONTINUE:
-    if(!continue_stack)
+    if(current_continue == -1)
     {
       yyerror("continue outside loop or switch.");
     }else{
-      if(current_continue>=continue_stack_size)
-      {
-	continue_stack_size*=2;
-	continue_stack=(int *)realloc((char *)continue_stack,
-				      sizeof(int)*continue_stack_size);
-      }
-      continue_stack[current_continue++]=do_jump(F_BRANCH,-1);
+      do_jump(F_BRANCH, current_continue);
     }
     return 0;
 
   case F_RETURN:
-    if(!CAR(n) ||
-       (CAR(n)->token == F_CONSTANT && IS_ZERO(&CAR(n)->u.sval)) ||
-       do_docode(CAR(n),0)<0)
-    {
-      ins_f_byte(F_RETURN_0);
-    }else{
-      ins_f_byte(F_RETURN);
-    }
+    do_docode(CAR(n),0);
+    emit2(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);
-    ins_f_byte_with_numerical_arg(F_SSCANF,tmp1+tmp2);
+    emit(F_SSCANF,tmp1+tmp2);
     return 1;
 
   case F_CATCH:
   {
-    struct jump_list cnt,brk;
+    INT32 break_save = current_break;
+    INT32 continue_save = current_continue;
     INT32 *prev_switch_jumptable = current_switch_jumptable;
+
     current_switch_jumptable=0;
+    current_break=alloc_label();
+    current_continue=alloc_label();
 
     tmp1=do_jump(F_CATCH,-1);
-    push_break_stack(&brk);
-    push_continue_stack(&cnt);
     DO_CODE_BLOCK(CAR(n));
-    pop_continue_stack(&cnt,PC);
-    pop_break_stack(&brk,PC);
-    ins_f_byte(F_DUMB_RETURN);
-    set_branch(tmp1,PC);
+    ins_label(current_continue);
+    ins_label(current_break);
+    emit2(F_DUMB_RETURN);
+    emit(F_LABEL,tmp1);
 
+    current_break=break_save;
+    current_continue=continue_save;
     current_switch_jumptable = prev_switch_jumptable;
     return 1;
   }
@@ -1149,12 +905,12 @@ static int do_docode2(node *n,int flags)
       tmp1=do_docode(CAR(n), DO_NOT_COPY);
       if(do_docode(CDR(n),DO_NOT_COPY) != 1)
 	fatal("Internal compiler error, please report this (1).");
-      ins_f_byte(F_INDEX);
+      emit2(F_INDEX);
       if(!(flags & DO_NOT_COPY))
       {
 	while(n && n->token==F_INDEX) n=CAR(n);
 	if(n->token==F_CONSTANT && !(n->node_info & OPT_EXTERNAL_DEPEND))
-	  ins_f_byte(F_COPY_VALUE);
+	  emit2(F_COPY_VALUE);
       }
     }
     return tmp1;
@@ -1163,16 +919,12 @@ static int do_docode2(node *n,int flags)
     switch(n->u.sval.type)
     {
     case T_INT:
-      ins_int(n->u.sval.u.integer);
-      return 1;
-
-    case T_FLOAT:
-      ins_float(n->u.sval.u.float_number);
+      emit(F_NUMBER,n->u.sval.u.integer);
       return 1;
 
     case T_STRING:
       tmp1=store_prog_string(n->u.sval.u.string);
-      ins_f_byte_with_numerical_arg(F_STRING,tmp1);
+      emit(F_STRING,tmp1);
       return 1;
 
     case T_FUNCTION:
@@ -1180,25 +932,25 @@ static int do_docode2(node *n,int flags)
       {
 	if(n->u.sval.u.object == &fake_object)
 	{
-	  ins_f_byte_with_numerical_arg(F_LFUN,n->u.sval.subtype);
+	  emit(F_LFUN,n->u.sval.subtype);
 	  return 1;
 	}
       }
 
     default:
       tmp1=store_constant(&(n->u.sval),!(n->tree_info & OPT_EXTERNAL_DEPEND));
-      ins_f_byte_with_numerical_arg(F_CONSTANT,tmp1);
+      emit(F_CONSTANT,tmp1);
       return 1;
 
     case T_ARRAY:
     case T_MAPPING:
     case T_LIST:
       tmp1=store_constant(&(n->u.sval),!(n->tree_info & OPT_EXTERNAL_DEPEND));
-      ins_f_byte_with_numerical_arg(F_CONSTANT,tmp1);
+      emit(F_CONSTANT,tmp1);
       
       /* copy now or later ? */
       if(!(flags & DO_NOT_COPY) && !(n->tree_info & OPT_EXTERNAL_DEPEND))
-	ins_f_byte(F_COPY_VALUE);
+	emit2(F_COPY_VALUE);
       return 1;
 
     }
@@ -1206,10 +958,10 @@ static int do_docode2(node *n,int flags)
   case F_LOCAL:
     if(flags & DO_LVALUE)
     {
-      ins_f_byte_with_numerical_arg(F_LOCAL_LVALUE,n->u.number);
+      emit(F_LOCAL_LVALUE,n->u.number);
       return 2;
     }else{
-      ins_f_byte_with_numerical_arg(F_LOCAL,n->u.number);
+      emit(F_LOCAL,n->u.number);
       return 1;
     }
 
@@ -1220,21 +972,21 @@ static int do_docode2(node *n,int flags)
       {
 	yyerror("Cannot assign functions.\n");
       }else{
-	ins_f_byte_with_numerical_arg(F_LFUN,n->u.number);
+	emit(F_LFUN,n->u.number);
       }
     }else{
       if(flags & DO_LVALUE)
       {
-	ins_f_byte_with_numerical_arg(F_GLOBAL_LVALUE,n->u.number);
+	emit(F_GLOBAL_LVALUE,n->u.number);
 	return 2;
       }else{
-	ins_f_byte_with_numerical_arg(F_GLOBAL,n->u.number);
+	emit(F_GLOBAL,n->u.number);
       }
     }
     return 1;
 
   case F_EFUN:
-    ins_f_byte_with_numerical_arg(n->token,n->u.number);
+    emit(n->token,n->u.number);
     return 1;
 
   case F_VAL_LVAL:
@@ -1248,6 +1000,28 @@ static int do_docode2(node *n,int flags)
 
 void do_code_block(node *n)
 {
-  clean_jumptable();
+  init_bytecode();
+  label_no=0;
   DO_CODE_BLOCK(n);
+  asm_opt();
+  assemble();
+}
+
+int docode(node *n)
+{
+  int tmp;
+  int label_no_save = label_no;
+  dynamic_buffer instrbuf_save = instrbuf;
+
+  instrbuf.s.str=0;
+  label_no=0;
+  init_bytecode();
+
+  tmp=do_docode(n,0);
+  asm_opt();
+  assemble();
+
+  instrbuf=instrbuf_save;
+  label_no = label_no_save;
+  return tmp;
 }