diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index 02ad7d76dc7e58011ecfe93f08cd0027254d94d2..d7144ae87f782b5d01a5f22536086a4796a3f202 100644
--- a/src/builtin_functions.c
+++ b/src/builtin_functions.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: builtin_functions.c,v 1.24 1997/01/29 00:06:23 hubbe Exp $");
+RCSID("$Id: builtin_functions.c,v 1.25 1997/01/30 03:51:31 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "macros.h"
@@ -1714,7 +1714,7 @@ void init_builtin_efuns()
   add_efun("sort",f_sort,"function(array(mixed),array(mixed)...:array(mixed))",OPT_SIDE_EFFECT);
   add_efun("stringp", f_stringp, "function(mixed:int)",0);
   add_efun("this_object", f_this_object, "function(:object)",OPT_EXTERNAL_DEPEND);
-  add_efun("throw",f_throw,"function(mixed:void)",0);
+  add_efun("throw",f_throw,"function(mixed:void)",OPT_SIDE_EFFECT);
   add_efun("time",f_time,"function(void|int:int)",OPT_EXTERNAL_DEPEND);
   add_efun("trace",f_trace,"function(int:int)",OPT_SIDE_EFFECT);
   add_efun("upper_case",f_upper_case,"function(string:string)",0);
diff --git a/src/docode.c b/src/docode.c
index ffd707790ebbe14308e1a0a14ea9f10f48ff653c..ab1b2e2c519d9522175db2e795014249064ac1ee 100644
--- a/src/docode.c
+++ b/src/docode.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: docode.c,v 1.9 1997/01/29 00:31:12 hubbe Exp $");
+RCSID("$Id: docode.c,v 1.10 1997/01/30 03:51:32 hubbe Exp $");
 #include "las.h"
 #include "program.h"
 #include "language.h"
@@ -959,7 +959,9 @@ static int do_docode2(node *n,int flags)
       tmp1=do_docode(CAR(n), 0);
       if(do_docode(CDR(n),0) != 1)
 	fatal("Internal compiler error, please report this (1).");
-      if(CDR(n)->token != F_CONSTANT) emit2(F_CLEAR_STRING_SUBTYPE);
+      if(CDR(n)->token != F_CONSTANT &&
+	match_types(CDR(n)->type, string_type_string))
+	emit2(F_CLEAR_STRING_SUBTYPE);
       return 2;
     }else{
       tmp1=do_docode(CAR(n), DO_NOT_COPY);
diff --git a/src/interpret.c b/src/interpret.c
index d1250faac907a905a27c3f712c3fd1c21085734e..96cae1370edb49e1fcbb06c8db5b1835a189d7b5 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: interpret.c,v 1.22 1997/01/29 01:02:03 hubbe Exp $");
+RCSID("$Id: interpret.c,v 1.23 1997/01/30 03:51:32 hubbe Exp $");
 #include "interpret.h"
 #include "object.h"
 #include "program.h"
@@ -469,29 +469,28 @@ static void eval_instruction(unsigned char *pc)
     fp->pc = pc;
     instr=EXTRACT_UCHAR(pc++);
 
-  again:
 #ifdef DEBUG
-#ifdef _REENTRANT
-    if(!mt_trylock(& interpreter_lock))
-      fatal("Interpreter running unlocked!\n");
-#endif
-    sp[0].type=99; /* an invalid type */
-    sp[1].type=99;
-    sp[2].type=99;
-    sp[3].type=99;
-
-    if(sp<evaluator_stack || mark_sp < mark_stack || fp->locals>sp)
-      fatal("Stack error (generic).\n");
-
-    if(sp > evaluator_stack+stack_size)
-      fatal("Stack error (overflow).\n");
-
-    if(fp->fun>=0 && fp->current_object->prog &&
-	fp->locals+fp->num_locals > sp)
-      fatal("Stack error (stupid!).\n");
-
     if(d_flag)
     {
+#ifdef _REENTRANT
+      if(!mt_trylock(& interpreter_lock))
+	fatal("Interpreter running unlocked!\n");
+#endif
+      sp[0].type=99; /* an invalid type */
+      sp[1].type=99;
+      sp[2].type=99;
+      sp[3].type=99;
+      
+      if(sp<evaluator_stack || mark_sp < mark_stack || fp->locals>sp)
+	fatal("Stack error (generic).\n");
+      
+      if(sp > evaluator_stack+stack_size)
+	fatal("Stack error (overflow).\n");
+      
+      if(fp->fun>=0 && fp->current_object->prog &&
+	 fp->locals+fp->num_locals > sp)
+	fatal("Stack error (stupid!).\n");
+      
       if(d_flag > 9) check_threads_etc();
 
       backlogp++;
@@ -514,6 +513,7 @@ static void eval_instruction(unsigned char *pc)
       if((nonblock=query_nonblocking(2)))
 	set_nonblocking(2,0);
 
+
       file=get_line(pc-1,fp->context.prog,&linep);
       while((f=STRCHR(file,'/'))) file=f+1;
       fprintf(stderr,"- %s:%4ld:(%lx): %-25s %4ld %4ld\n",
@@ -532,13 +532,6 @@ static void eval_instruction(unsigned char *pc)
 
     switch(instr)
     {
-      /* Support for large instructions */
-      CASE(F_ADD_256); instr=EXTRACT_UCHAR(pc++)+256; goto again;
-      CASE(F_ADD_512); instr=EXTRACT_UCHAR(pc++)+512; goto again;
-      CASE(F_ADD_768); instr=EXTRACT_UCHAR(pc++)+768; goto again;
-      CASE(F_ADD_1024);instr=EXTRACT_UCHAR(pc++)+1024;goto again;
-      CASE(F_ADD_256X); instr=EXTRACT_UWORD(pc); pc+=sizeof(INT16); goto again;
-
       /* Support to allow large arguments */
       CASE(F_PREFIX_256); prefix+=256; break;
       CASE(F_PREFIX_512); prefix+=512; break;
@@ -605,11 +598,20 @@ static void eval_instruction(unsigned char *pc)
       print_return_value();
       break;
 
+      CASE(F_MARK_AND_LOCAL); *(mark_sp++)=sp;
       CASE(F_LOCAL);
       assign_svalue_no_free(sp++,fp->locals+GET_ARG());
       print_return_value();
       break;
 
+      CASE(F_2_LOCALS);
+      assign_svalue_no_free(sp++,fp->locals+GET_ARG());
+      print_return_value();
+      assign_svalue_no_free(sp++,fp->locals+GET_ARG());
+      print_return_value();
+      break;
+      
+
       CASE(F_LOCAL_LVALUE);
       sp[0].type=T_LVALUE;
       sp[0].u.lval=fp->locals+GET_ARG();
@@ -617,6 +619,17 @@ static void eval_instruction(unsigned char *pc)
       sp+=2;
       break;
 
+      CASE(F_CLEAR_2_LOCAL);
+      instr=GET_ARG();
+      free_svalues(fp->locals + instr, 2, -1);
+      fp->locals[instr].type=T_INT;
+      fp->locals[instr].subtype=0;
+      fp->locals[instr].u.integer=0;
+      fp->locals[instr+1].type=T_INT;
+      fp->locals[instr+1].subtype=0;
+      fp->locals[instr+1].u.integer=0;
+      break;
+
       CASE(F_CLEAR_LOCAL);
       instr=GET_ARG();
       free_svalue(fp->locals + instr);
@@ -1012,6 +1025,8 @@ static void eval_instruction(unsigned char *pc)
 
       CASE(F_LOCAL_INDEX);
       assign_svalue_no_free(sp++,fp->locals+GET_ARG());
+      if(sp[-1].type == T_STRING)
+	sp[-1].subtype=0;
       print_return_value();
       goto do_index;
 
@@ -1084,16 +1099,17 @@ static void eval_instruction(unsigned char *pc)
       pop_stack();
       break;
 
+    CASE(F_APPLY);
+      strict_apply_svalue(fp->context.prog->constants + GET_ARG(), sp - *--mark_sp );
+      break;
+
+    CASE(F_APPLY_AND_POP);
+      strict_apply_svalue(fp->context.prog->constants + GET_ARG(), sp - *--mark_sp );
+      pop_stack();
+      break;
+
     default:
-      instr -= F_MAX_OPCODE - F_OFFSET;
-#ifdef DEBUG
-      if(instr >= fp->context.prog->num_constants)
-      {
-	instr += F_MAX_OPCODE - F_OFFSET;
-	fatal("Strange instruction %ld\n",(long)instr);
-      }
-#endif      
-      strict_apply_svalue(fp->context.prog->constants + instr, sp - *--mark_sp );
+      fatal("Strange instruction %ld\n",(long)instr);
     }
   }
 }
diff --git a/src/language.yacc b/src/language.yacc
index 06b1972dfcb9d8f9904cf596b260d589f8138241..8e34f12f46e2fcf8cb7b358891889bc811aa559d 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -9,11 +9,11 @@
  * These values are used by the stack machine, and can not be directly
  * called from Pike.
  */
-%token F_ADD_256 F_ADD_512 F_ADD_768 F_ADD_1024 F_ADD_256X
 %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_POP_VALUE F_POP_N_ELEMS F_MARK F_MARK2
 %token F_CALL_LFUN F_CALL_LFUN_AND_POP
+%token F_APPLY F_APPLY_AND_POP
 
 %token F_BRANCH F_BRANCH_WHEN_ZERO F_BRANCH_WHEN_NON_ZERO
 %token F_BRANCH_WHEN_LT F_BRANCH_WHEN_GT
@@ -31,9 +31,9 @@
 /*
  * Basic value pushing
  */
-%token F_LFUN F_GLOBAL F_LOCAL
+%token F_LFUN F_GLOBAL F_LOCAL F_2_LOCALS F_MARK_AND_LOCAL
 %token F_GLOBAL_LVALUE F_LOCAL_LVALUE
-%token F_CLEAR_LOCAL F_CLEAR_STRING_SUBTYPE
+%token F_CLEAR_LOCAL F_CLEAR_2_LOCAL F_CLEAR_STRING_SUBTYPE
 %token F_CONSTANT F_FLOAT F_STRING F_ARROW_STRING
 %token F_NUMBER F_NEG_NUMBER F_CONST_1 F_CONST0 F_CONST1 F_BIGNUM
 /*
@@ -71,7 +71,6 @@
 %token F_MAX_OPCODE
 %token F_ADD_EQ
 %token F_AND_EQ
-%token F_APPLY
 %token F_ARG_LIST
 %token F_ARRAY_ID
 %token F_BREAK
@@ -133,6 +132,7 @@
 %token F_ALIGN
 %token F_POINTER
 %token F_LABEL
+%token F_BYTE
 
 %token F_MAX_INSTR
 
@@ -156,7 +156,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.20 1997/01/29 01:05:58 hubbe Exp $");
+RCSID("$Id: language.yacc,v 1.21 1997/01/30 03:51:33 hubbe Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
diff --git a/src/las.c b/src/las.c
index 84ea9384ef1a70984eb26c50439dbbcaad8416e0..991a401d3b1a35a5e549d5ca7fbe1eafebe7aff1 100644
--- a/src/las.c
+++ b/src/las.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: las.c,v 1.15 1997/01/28 03:04:31 hubbe Exp $");
+RCSID("$Id: las.c,v 1.16 1997/01/30 03:51:34 hubbe Exp $");
 
 #include "language.h"
 #include "interpret.h"
@@ -39,7 +39,7 @@ int num_parse_error;
 int cumulative_parse_error=0;
 extern char *get_type_name(int);
 
-#define MAX_GLOBAL 256
+#define MAX_GLOBAL 2048
 
 int car_is_node(node *n)
 {
@@ -537,8 +537,10 @@ node *mkconstantsvaluenode(struct svalue *s)
   node *res = mkemptynode();
   res->token = F_CONSTANT;
   assign_svalue_no_free(& res->u.sval, s);
-  if(s->type == T_OBJECT || s->type==T_FUNCTION)
+  if(s->type == T_OBJECT || (s->type==T_FUNCTION && s->subtype!=FUNCTION_BUILTIN))
+  {
     res->node_info|=OPT_EXTERNAL_DEPEND;
+  }
   res->type = get_type_of_svalue(s);
   return res;
 }
@@ -860,6 +862,7 @@ void print_tree(node *n)
 /* The following routines needs much better commenting */
 struct used_vars
 {
+  int err;
   char locals[MAX_LOCAL];
   char globals[MAX_GLOBAL];
 };
@@ -873,6 +876,7 @@ static void do_and_vars(struct used_vars *a,struct used_vars *b)
   int e;
   for(e=0;e<MAX_LOCAL;e++) a->locals[e]|=b->locals[e];
   for(e=0;e<MAX_GLOBAL;e++) a->globals[e]|=b->globals[e];
+  a->err|=b->err;
   free((char *)b);
 }
 
@@ -901,6 +905,11 @@ static int find_used_variables(node *n,
 
   case F_IDENTIFIER:
     q=p->globals+n->u.number;
+    if(n->u.number > MAX_GLOBAL)
+    {
+      p->err=1;
+      return 0;
+    }
 
   set_pointer:
     if(overwrite)
@@ -909,7 +918,7 @@ static int find_used_variables(node *n,
     }
     else
     {
-      if(*q != VAR_UNUSED) *q = VAR_USED;
+      if(*q == VAR_UNUSED) *q = VAR_USED;
     }
     break;
 
@@ -973,7 +982,20 @@ static void find_written_vars(node *n,
     break;
 
   case F_GLOBAL:
-    if(lvalue) p->globals[n->u.number]=VAR_USED;
+     if(lvalue)
+     {
+       if(n->u.number>=MAX_GLOBAL)
+       {
+	 p->err=1;
+	 return;
+       }
+       p->globals[n->u.number]=VAR_USED;
+     }
+    break;
+
+  case F_APPLY:
+    if(n->tree_info & OPT_SIDE_EFFECT)
+      MEMSET(p->globals, MAX_GLOBAL, VAR_USED);
     break;
 
   case F_INDEX:
@@ -1028,6 +1050,8 @@ static int depend_p2(node *a,node *b)
   find_used_variables(a,&aa,0,0);
   find_written_vars(b,&bb,0);
 
+  if(aa.err || bb.err) return 1;
+
   for(e=0;e<MAX_LOCAL;e++)
     if(aa.locals[e]==VAR_USED && bb.locals[e]!=VAR_UNUSED)
       return 1;
@@ -1041,9 +1065,13 @@ static int depend_p2(node *a,node *b)
 static int depend_p(node *a,node *b)
 {
   if(!b) return 0;
+#if 0
   if(!(b->tree_info & OPT_SIDE_EFFECT) && 
      (b->tree_info & OPT_EXTERNAL_DEPEND))
     return 1;
+#endif
+
+  if((a->tree_info & OPT_EXTERNAL_DEPEND)) return 1;
     
   return depend_p2(a,b);
 }
diff --git a/src/lex.c b/src/lex.c
index 07b4848306b8b0c05ce2b5f767afbbbf43f7603f..b8ad459bb1a1c72e1ffb3bdcaa633b3580f4f6a2 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: lex.c,v 1.13 1997/01/27 01:20:04 hubbe Exp $");
+RCSID("$Id: lex.c,v 1.14 1997/01/30 03:51:34 hubbe Exp $");
 #include "language.h"
 #include "array.h"
 #include "lex.h"
@@ -57,7 +57,7 @@ static void calc1();
 void exit_lex()
 {
 #ifdef DEBUG
-  if(p_flag > 2)
+  if(p_flag)
   {
     int e;
     fprintf(stderr,"Opcode usage: (opcode, runned, compiled)\n");
@@ -144,22 +144,21 @@ struct keyword instr_names[]=
 { "!=",			F_NE },	
 { "%",			F_MOD },	
 { "%=",			F_MOD_EQ },	
-{ "& global",           F_GLOBAL_LVALUE },
-{ "& local",            F_LOCAL_LVALUE },
+{ "& global",           F_GLOBAL_LVALUE, 1 },
+{ "& local",            F_LOCAL_LVALUE, 1 },
 { "&",			F_AND },
-{ "&&",			F_LAND },	
+{ "&&",			F_LAND, 1 },	
 { "&=",			F_AND_EQ },	
 { "*",			F_MULTIPLY },	
 { "*=",			F_MULT_EQ },	
 { "+",			F_ADD },	
-{ "++Loop",		F_INC_LOOP },	
-{ "++Loop!=",		F_INC_NEQ_LOOP },
+{ "++Loop",		F_INC_LOOP, 1 },	
+{ "++Loop!=",		F_INC_NEQ_LOOP, 1 },
 { "++x",		F_INC },	
 { "+=",			F_ADD_EQ },	
 { "-",			F_SUBTRACT },	
-{ "-",			F_SUBTRACT },	
-{ "--Loop",		F_DEC_LOOP },	
-{ "--Loop!=",		F_DEC_NEQ_LOOP },
+{ "--Loop",		F_DEC_LOOP, 1 },	
+{ "--Loop!=",		F_DEC_NEQ_LOOP, 1 },
 { "--x",		F_DEC },	
 { "-=",			F_SUB_EQ },	
 { "/",			F_DIVIDE },	
@@ -176,11 +175,6 @@ struct keyword instr_names[]=
 { "@",			F_PUSH_ARRAY },
 { "^",			F_XOR },
 { "^=",			F_XOR_EQ },	
-{ "add 1024 to opcode",	F_ADD_1024 },
-{ "add 256 to opcode",	F_ADD_256 },	
-{ "add 512 to opcode",	F_ADD_512 },	
-{ "add 768 to opcode",	F_ADD_768 },	
-{ "add X*256 to opcode",F_ADD_256X },	
 { "arg+=1024",		F_PREFIX_1024 },
 { "arg+=256",		F_PREFIX_256 },
 { "arg+=256*X",		F_PREFIX_CHARX256 },
@@ -189,19 +183,19 @@ struct keyword instr_names[]=
 { "arg+=512",		F_PREFIX_512 },
 { "arg+=768",		F_PREFIX_768 },
 { "assign and pop",	F_ASSIGN_AND_POP },
-{ "assign global",	F_ASSIGN_GLOBAL },
-{ "assign global and pop",	F_ASSIGN_GLOBAL_AND_POP },
-{ "assign local",       F_ASSIGN_LOCAL },
-{ "assign local and pop",	F_ASSIGN_LOCAL_AND_POP },
+{ "assign global",	F_ASSIGN_GLOBAL, 1 },
+{ "assign global and pop",	F_ASSIGN_GLOBAL_AND_POP, 1 },
+{ "assign local",       F_ASSIGN_LOCAL, 1 },
+{ "assign local and pop",	F_ASSIGN_LOCAL_AND_POP, 1 },
 { "assign",		F_ASSIGN },
-{ "branch non zero",	F_BRANCH_WHEN_NON_ZERO },	
-{ "branch when zero",	F_BRANCH_WHEN_ZERO },	
+{ "branch non zero",	F_BRANCH_WHEN_NON_ZERO, 1 },	
+{ "branch when zero",	F_BRANCH_WHEN_ZERO, 1 },	
 { "break",		F_BREAK },	
 { "case",		F_CASE },	
 { "cast",		F_CAST },	
-{ "catch",		F_CATCH },
+{ "catch",		F_CATCH, 1 },
 { "const-1",		F_CONST_1 },	
-{ "constant",           F_CONSTANT },
+{ "constant",           F_CONSTANT, 1 },
 { "continue",		F_CONTINUE },	
 { "copy_value",         F_COPY_VALUE },
 { "default",		F_DEFAULT },	
@@ -209,36 +203,37 @@ struct keyword instr_names[]=
 { "dumb return",	F_DUMB_RETURN },	
 { "float number",	F_FLOAT },
 { "for",		F_FOR },
-{ "foreach",		F_FOREACH },
-{ "global",		F_GLOBAL },
+{ "foreach",		F_FOREACH, 1 },
+{ "global",		F_GLOBAL, 1 },
 { "index",              F_INDEX },
-{ "->",                 F_ARROW },
+{ "->",                 F_ARROW, 1 },
 { "clear string subtype", F_CLEAR_STRING_SUBTYPE },
-{ "arrow string",       F_ARROW_STRING },
+{ "arrow string",       F_ARROW_STRING, 1 },
 { "indirect",		F_INDIRECT },
-{ "jump",               F_BRANCH },
-{ "local function call",F_CALL_LFUN },
-{ "local function call and pop",F_CALL_LFUN_AND_POP },
-{ "local function",	F_LFUN },	
-{ "local",		F_LOCAL },	
+{ "jump",               F_BRANCH, 1 },
+{ "local function call",F_CALL_LFUN, 1 },
+{ "local function call and pop",F_CALL_LFUN_AND_POP, 1 },
+{ "local function",	F_LFUN, 1 },	
+{ "local",		F_LOCAL, 1 },	
+{ "mark & local",	F_MARK_AND_LOCAL, 1 },	
 { "ltosval2",		F_LTOSVAL2 },
 { "lvalue to svalue",	F_LTOSVAL },	
 { "lvalue_list",	F_LVALUE_LIST },	
 { "mark",               F_MARK },
 { "mark mark",          F_MARK2 },
-{ "negative number",	F_NEG_NUMBER },
-{ "number",             F_NUMBER },
+{ "negative number",	F_NEG_NUMBER, 1 },
+{ "number",             F_NUMBER, 1 },
 { "pop",		F_POP_VALUE },	
-{ "pop_n_elems",        F_POP_N_ELEMS },
+{ "pop_n_elems",        F_POP_N_ELEMS, 1 },
 { "push 0",             F_CONST0 },
 { "push 1",             F_CONST1 },
 { "push 0x7fffffff",    F_BIGNUM },
 { "range",              F_RANGE },
 { "return",		F_RETURN },
 { "return 0",		F_RETURN_0 },
-{ "sscanf",		F_SSCANF },	
-{ "string",             F_STRING },
-{ "switch",		F_SWITCH },
+{ "sscanf",		F_SSCANF, 1 },	
+{ "string",             F_STRING, 1 },
+{ "switch",		F_SWITCH, 1 },
 { "unary minus",	F_NEGATE },
 { "while",		F_WHILE },	
 { "x++ and pop",	F_INC_AND_POP },	
@@ -247,32 +242,36 @@ struct keyword instr_names[]=
 { "x--",		F_POST_DEC },	
 { "|",			F_OR },
 { "|=",			F_OR_EQ },	
-{ "||",			F_LOR },	
+{ "||",			F_LOR, 1 },	
 { "~",			F_COMPL },
-{ "label",		F_LABEL },
-{ "data",		F_POINTER },
-{ "align",		F_ALIGN },
-{ "call",		F_APPLY },
-{ "clear local",	F_CLEAR_LOCAL },
-{ "++local",		F_INC_LOCAL },
-{ "++local and pop",	F_INC_LOCAL_AND_POP },
-{ "local++",		F_POST_INC_LOCAL },
-{ "--local",		F_DEC_LOCAL },
-{ "--local and pop",	F_DEC_LOCAL_AND_POP },
-{ "local--",		F_POST_DEC_LOCAL },
-{ "branch if <",	F_BRANCH_WHEN_LT },
-{ "branch if >",	F_BRANCH_WHEN_GT },
-{ "branch if <=",	F_BRANCH_WHEN_LE },
-{ "branch if >=",	F_BRANCH_WHEN_GE },
-{ "branch if ==",	F_BRANCH_WHEN_EQ },
-{ "branch if !=",	F_BRANCH_WHEN_NE },
+{ "label",		F_LABEL,1 },
+{ "data",		F_POINTER, 1 },
+{ "align",		F_ALIGN, 1 },
+{ "call",		F_APPLY, 1 },
+{ "clear local",	F_CLEAR_LOCAL, 1 },
+{ "clear 2 local",	F_CLEAR_2_LOCAL, 1 },
+{ "++local",		F_INC_LOCAL, 1 },
+{ "++local and pop",	F_INC_LOCAL_AND_POP, 1 },
+{ "local++",		F_POST_INC_LOCAL, 1 },
+{ "--local",		F_DEC_LOCAL, 1 },
+{ "--local and pop",	F_DEC_LOCAL_AND_POP, 1 },
+{ "local--",		F_POST_DEC_LOCAL, 1 },
+{ "branch if <",	F_BRANCH_WHEN_LT, 1 },
+{ "branch if >",	F_BRANCH_WHEN_GT, 1 },
+{ "branch if <=",	F_BRANCH_WHEN_LE, 1 },
+{ "branch if >=",	F_BRANCH_WHEN_GE, 1 },
+{ "branch if ==",	F_BRANCH_WHEN_EQ, 1 },
+{ "branch if !=",	F_BRANCH_WHEN_NE, 1 },
 { "sizeof",		F_SIZEOF },
-{ "sizeof local",	F_SIZEOF_LOCAL },
+{ "sizeof local",	F_SIZEOF_LOCAL, 1 },
 { "throw(0)",		F_THROW_ZERO },
-{ "string index",       F_STRING_INDEX },
-{ "local index",        F_LOCAL_INDEX },
-{ "int index",          F_POS_INT_INDEX },
-{ "-int index",         F_NEG_INT_INDEX },
+{ "string index",       F_STRING_INDEX, 1 },
+{ "local index",        F_LOCAL_INDEX, 1 },
+{ "int index",          F_POS_INT_INDEX, 1 },
+{ "-int index",         F_NEG_INT_INDEX, 1 },
+{ "apply and pop",      F_APPLY_AND_POP, 1 },
+{ "2 locals",           F_2_LOCALS, 1 },
+{ "byte",               F_BYTE, 1 },
 };
 
 struct instr instrs[F_MAX_INSTR - F_OFFSET];
@@ -292,7 +291,12 @@ void init_lex()
   {
     if(instr_names[i].token >= F_MAX_INSTR)
       fatal("Error in instr_names[%u]\n\n",i);
+
+    if(instrs[instr_names[i].token - F_OFFSET].name)
+      fatal("Duplicate name for %s\n",instr_names[i].word);
+
     instrs[instr_names[i].token - F_OFFSET].name = instr_names[i].word;
+    instrs[instr_names[i].token - F_OFFSET].hasarg=instr_names[i].hasarg;
   }
 
   reswords=create_hash_table();
diff --git a/src/lex.h b/src/lex.h
index f5ce12941d12e8952269124e6444de8ac71b64a7..381f0786a62c84b5b40033774ab164a21cc4bb37 100644
--- a/src/lex.h
+++ b/src/lex.h
@@ -12,6 +12,7 @@ struct keyword
 {
   char *word;
   int token;
+  int hasarg;
 };
 
 struct instr
@@ -20,6 +21,7 @@ struct instr
   long runs;
   long compiles;
 #endif
+  int hasarg;
   char *name;
 };
 
diff --git a/src/peep.c b/src/peep.c
index cf262eb450fb70976594a4bd77a23976000e7740..121769ed5090059f0ca645a475883185b950f704 100644
--- a/src/peep.c
+++ b/src/peep.c
@@ -22,78 +22,7 @@ typedef struct p_instr_s p_instr;
 
 dynamic_buffer instrbuf;
 
-static int hasarg(int opcode)
-{
-  switch(opcode)
-  {
-  case F_NUMBER:
-  case F_NEG_NUMBER:
-  case F_CALL_LFUN:
-  case F_CALL_LFUN_AND_POP:
-  case F_SSCANF:
-  case F_POP_N_ELEMS:
-
-  case F_SIZEOF_LOCAL:
-
-  case F_ASSIGN_GLOBAL:
-  case F_ASSIGN_GLOBAL_AND_POP:
-  case F_ASSIGN_LOCAL:
-  case F_ASSIGN_LOCAL_AND_POP:
-  case F_GLOBAL_LVALUE:
-  case F_LOCAL_LVALUE:
-  case F_CLEAR_LOCAL:
-  case F_LOCAL:
-  case F_GLOBAL:
-
-  case F_INC_LOCAL:
-  case F_DEC_LOCAL:
-  case F_POST_INC_LOCAL:
-  case F_POST_DEC_LOCAL:
-  case F_INC_LOCAL_AND_POP:
-  case F_DEC_LOCAL_AND_POP:
-
-  case F_LFUN:
-  case F_STRING:
-  case F_ARROW:
-  case F_ARROW_STRING:
-  case F_STRING_INDEX:
-  case F_LOCAL_INDEX:
-  case F_POS_INT_INDEX:
-  case F_NEG_INT_INDEX:
-  case F_CONSTANT:
-  case F_SWITCH:
-  case F_APPLY:
-  case F_CATCH:
-
-  case F_BRANCH:
-  case F_BRANCH_WHEN_ZERO:
-  case F_BRANCH_WHEN_NON_ZERO:
-
-  case F_BRANCH_WHEN_EQ:
-  case F_BRANCH_WHEN_NE:
-  case F_BRANCH_WHEN_LT:
-  case F_BRANCH_WHEN_LE:
-  case F_BRANCH_WHEN_GT:
-  case F_BRANCH_WHEN_GE:
-
-  case F_FOREACH:
-  case F_INC_LOOP:
-  case F_DEC_LOOP:
-  case F_INC_NEQ_LOOP:
-  case F_DEC_NEQ_LOOP:
-
-  case F_LAND:
-  case F_LOR:
-
-  case F_ALIGN:
-  case F_POINTER:
-  case F_LABEL:
-    return 1;
-    
-  default:
-    return 0;
-  }
-}
+static int hasarg(int opcode) { return instrs[opcode-F_OFFSET].hasarg; }
 
 void init_bytecode()
 {
@@ -170,20 +99,10 @@ void ins_f_byte(unsigned int b)
     ADD_COMPILED(b);
 
   b-=F_OFFSET;
+#ifdef DEBUG
   if(b>255)
-  {
-    switch(b >> 8)
-    {
-    case 1: ins_f_byte(F_ADD_256); break;
-    case 2: ins_f_byte(F_ADD_512); break;
-    case 3: ins_f_byte(F_ADD_768); break;
-    case 4: ins_f_byte(F_ADD_1024); break;
-    default:
-      ins_f_byte(F_ADD_256X);
-      ins_byte(b/256,A_PROGRAM);
-    }
-    b&=255;
-  }
+    error("Instruction too big %d\n",b);
+#endif
   ins_byte((unsigned char)b,A_PROGRAM);
 }
 
@@ -260,6 +179,10 @@ void assemble()
       while(PC % c->arg) ins_byte(0, A_PROGRAM);
       break;
 
+    case F_BYTE:
+      ins_byte(c->arg, A_PROGRAM);
+      break;
+
     case F_LABEL:
 #ifdef DEBUG
       if(c->arg > max_label || c->arg < 0)
@@ -309,10 +232,6 @@ void assemble()
       jumps[c->arg]=tmp;
       break;
 
-    case F_APPLY:
-      ins_f_byte(c->arg + F_MAX_OPCODE);
-      break;
-
     default:
       if(hasarg(c->opcode))
 	ins_f_byte_with_arg(c->opcode, c->arg);
diff --git a/src/peep.in b/src/peep.in
index 1663a3fba3635ffd2c9fb3e380c49be0addaf69e..091248c82d789399bcc924ad94a6eaa1d189b104 100644
--- a/src/peep.in
+++ b/src/peep.in
@@ -10,6 +10,7 @@ MARK MARK: MARK2
 ASSIGN_GLOBAL POP_VALUE : ASSIGN_GLOBAL_AND_POP($1a)
 ASSIGN_LOCAL  POP_VALUE : ASSIGN_LOCAL_AND_POP($1a)
 CALL_LFUN POP_VALUE : CALL_LFUN_AND_POP($1a)
+APPLY POP_VALUE : APPLY_AND_POP($1a)
 NUMBER(0) : CONST0
 NUMBER(1) : CONST1
 NUMBER(-1) : CONST_1
@@ -23,6 +24,8 @@ NEG_NUMBER NEGATE : NUMBER ($1a)
 NEGATE CONST_1 ADD : COMPL
 NEGATE CONST1 SUBTRACT : COMPL
 CONST0 ASSIGN_LOCAL_AND_POP : CLEAR_LOCAL($2a)
+CLEAR_LOCAL NUMBER(0) ASSIGN_LOCAL_AND_POP ($1a) : CLEAR_LOCAL($1a)
+CLEAR_LOCAL NUMBER(0) ASSIGN_LOCAL_AND_POP ($1a+1) : CLEAR_2_LOCAL($1a)
 
 CONST_1 MULTIPLY : NEGATE
 #CONST0 MULTIPLY : POP_VALUE CONST0
@@ -97,6 +100,8 @@ GT NOT: LE
 LE NOT: GT
 GE NOT: LT
 
+LOCAL LOCAL [$2a<256 && $3o != F_SIZEOF && $3o != F_INDEX ]: 2_LOCALS ($1a) BYTE ($2a)
+MARK LOCAL [ $3o != F_SIZEOF && $3o != F_INDEX ]: MARK_AND_LOCAL ($2a)
 LOCAL SIZEOF: SIZEOF_LOCAL ($1a)
 STRING INDEX: STRING_INDEX ($1a)
 LOCAL INDEX: LOCAL_INDEX ($1a)
diff --git a/src/pike_types.c b/src/pike_types.c
index b417f06f2e32a8cfab831ec9bb7d5683a3f73e61..d362b63a6b9771cf30fbc128b4bae0b3d471847b 100644
--- a/src/pike_types.c
+++ b/src/pike_types.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: pike_types.c,v 1.14 1997/01/27 01:28:34 hubbe Exp $");
+RCSID("$Id: pike_types.c,v 1.15 1997/01/30 03:51:36 hubbe Exp $");
 #include <ctype.h>
 #include "svalue.h"
 #include "pike_types.h"
@@ -1137,6 +1137,16 @@ struct pike_string *get_type_of_svalue(struct svalue *s)
     push_type(T_OBJECT);
     return pop_type();
 
+  case T_INT:
+    if(s->u.integer)
+    {
+      ret=int_type_string;
+    }else{
+      ret=mixed_type_string;
+    }
+    reference_shared_string(ret);
+    return ret;
+
   default:
     push_type(s->type);
     return pop_type();
diff --git a/src/port.h b/src/port.h
index 1d98042df0da68dd115bda03fd9e99d6db8fcc40..f8fd4d7de0bcb60d46d424696a00215fc263d270 100644
--- a/src/port.h
+++ b/src/port.h
@@ -149,7 +149,7 @@ int VSPRINTF(char *buf,char *fmt,va_list args);
 #ifdef EXTRACT_UCHAR_BY_CAST
 #  define EXTRACT_UCHAR(p) (*(unsigned char *)(p))
 #else
-static INLINE int EXTRACT_UCHAR(char *p) { return *p < 0 ? *p + 0x100 : *p; }
+#  define EXTRACT_UCHAR(p) (0xff & (int)*(p))
 #endif
 
 #ifdef EXTRACT_CHAR_BY_CAST