diff --git a/src/pike_types.c b/src/pike_types.c
index 5c16993dadcc745beacf9c0032288da6b48419fe..a0caa6386212b092fa926c259a09d77af2b504e3 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.38 1998/04/10 22:24:21 hubbe Exp $");
+RCSID("$Id: pike_types.c,v 1.39 1998/04/14 22:10:49 hubbe Exp $");
 #include <ctype.h>
 #include "svalue.h"
 #include "pike_types.h"
@@ -645,7 +645,15 @@ char *low_describe_type(char *t)
     case T_FLOAT: my_strcat("float"); break;
     case T_PROGRAM: my_strcat("program"); break;
     case T_OBJECT:
-      my_strcat("object");
+      if(EXTRACT_INT(t+1))
+      {
+	char buffer[100];
+	sprintf(buffer,"object(%s %ld)",*t?"is":"implements",(long)EXTRACT_INT(t+1));
+	my_strcat(buffer);
+      }else{
+	my_strcat("object");
+      }
+      
       t+=sizeof(INT32)+1;
       /* Prog id */
       break;
@@ -856,12 +864,7 @@ static struct pike_string *low_object_fun_type(char *t,
   if(!p) return 0;
   i=FIND_LFUN(p, LFUN_CALL);
 
-  if(EXTRACT_UCHAR(t+1) ||
-     (p->identifier_references[i].id_flags & ID_NOMASK) ||
-    (ID_FROM_INT(p, i)->identifier_flags & IDENTIFIER_PROTOTYPED))
-    return ID_FROM_INT(p, i)->type;
-
-  return 0;
+  return ID_FROM_INT(p, i)->type;
 }
 
 static struct pike_string *low_object_lfun_type(char *t, short lfun)
@@ -872,12 +875,7 @@ static struct pike_string *low_object_lfun_type(char *t, short lfun)
   if(!p) return 0;
   i=FIND_LFUN(p, LFUN_CALL);
 
-  if(EXTRACT_UCHAR(t+1) ||
-     (p->identifier_references[i].id_flags & ID_NOMASK) ||
-    (ID_FROM_INT(p, i)->identifier_flags & IDENTIFIER_PROTOTYPED))
-    return ID_FROM_INT(p, i)->type;
-
-  return 0;
+  return ID_FROM_INT(p, i)->type;
 }
 
 #define A_EXACT 1
@@ -1090,10 +1088,10 @@ static char *low_match_types(char *a,char *b, int flags)
       
       if(EXTRACT_UCHAR(a+1))
       {
-	if(low_get_storage(bp,ap)==-1)
+	if(!implements(ap,bp))
 	  return 0;
       }else{
-	if(low_get_storage(ap,bp)==-1)
+	if(!implements(bp,ap))
 	  return 0;
       }
     }
diff --git a/src/program.c b/src/program.c
index 1996e4b7eb8555d4ab17e140f9bc89981bc01504..cbb34db8e6ecf6cb5e9a42809a7f962f1425b152 100644
--- a/src/program.c
+++ b/src/program.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: program.c,v 1.79 1998/04/14 19:24:12 grubba Exp $");
+RCSID("$Id: program.c,v 1.80 1998/04/14 22:10:50 hubbe Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -2023,12 +2023,19 @@ void my_yyerror(char *fmt,...)  ATTRIBUTE((format(printf,1,2)))
 
 struct program *compile(struct pike_string *prog)
 {
+#ifdef DEBUG
+  JMP_BUF tmp;
+#endif
   struct program *p;
   struct lex save_lex;
   int save_depth=compilation_depth;
   int saved_threads_disabled = threads_disabled;
   void yyparse(void);
-  ONERROR just_in_case;
+
+#ifdef DEBUG
+  if(SETJMP(tmp))
+    fatal("Compiler exited with longjump!\n");
+#endif
 
   save_lex=lex;
 
@@ -2037,11 +2044,6 @@ struct program *compile(struct pike_string *prog)
   lex.current_file=make_shared_string("-");
   lex.pragmas=0;
 
-  threads_disabled++;
-  SET_ONERROR(just_in_case, restore_threads_disabled, saved_threads_disabled);
-
-  /* fprintf(stderr, "compile() Enter: threads_disabled:%d, compilation_depth:%d\n", threads_disabled, compilation_depth); */
-
   start_new_program();
   compilation_depth=0;
 
@@ -2049,6 +2051,7 @@ struct program *compile(struct pike_string *prog)
 
   compiler_pass=1;
   lex.pos=prog->str;
+
   yyparse();  /* Parse da program */
 
   p=end_first_pass(0);
@@ -2074,13 +2077,15 @@ struct program *compile(struct pike_string *prog)
   /* fprintf(stderr, "compile() Leave: threads_disabled:%d, compilation_depth:%d\n", threads_disabled, compilation_depth); */
   co_signal(&threads_disabled_change);
 
-  UNSET_ONERROR(just_in_case);
-
   free_string(lex.current_file);
   lex=save_lex;
 
   compilation_depth=save_depth;
 
+#ifdef DEBUG
+  UNSETJMP(tmp);
+#endif
+
   if(!p) error("Compilation failed.\n");
   return p;
 }
@@ -2467,3 +2472,49 @@ void yywarning(char *fmt, ...) ATTRIBUTE((format(printf,1,2)))
     pop_stack();
   }
 }
+
+
+
+/* returns 1 if a implements b */
+static int low_implements(struct program *a, struct program *b)
+{
+  int e,num=0;
+  struct pike_string *s=findstring("__INIT");
+  for(e=0;e<b->num_identifier_references;e++)
+  {
+    struct identifier *bid=ID_FROM_INT(b,e);
+    int i;
+    if(s==bid->name) continue;
+    i=find_shared_string_identifier(bid->name,a);
+    if(i!=-1)
+    {
+      if(!match_types(ID_FROM_INT(a,i)->type, bid->type))
+	return 0;
+      fprintf(stderr,"%s\n",bid->name->str);
+      num++;
+    }
+  }
+  return num;
+}
+
+#define IMPLEMENTS_CACHE_SIZE 4711
+struct implements_cache_s { INT32 aid, bid, ret; };
+static struct implements_cache_s implements_cache[IMPLEMENTS_CACHE_SIZE];
+
+/* returns 1 if a implements b, but faster */
+int implements(struct program *a, struct program *b)
+{
+  unsigned long hval;
+  if(!a || !b) return -1;
+  if(a==b) return 1;
+  hval = a->id*9248339 + b->id;
+  hval %= IMPLEMENTS_CACHE_SIZE;
+  if(implements_cache[hval].aid==a->id && implements_cache[hval].bid==b->id)
+  {
+    return implements_cache[hval].ret;
+  }
+  /* Do it the tedious way */
+  implements_cache[hval].aid=a->id;
+  implements_cache[hval].bid=b->id;
+  return implements_cache[hval].ret=low_implements(a,b);
+}
diff --git a/src/program.h b/src/program.h
index 28cc72511024d0492c6a767aabc4cc90d8789884..b28c2c61cd900b259732851160e39ff57fe43481 100644
--- a/src/program.h
+++ b/src/program.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: program.h,v 1.39 1998/04/10 22:24:22 hubbe Exp $
+ * $Id: program.h,v 1.40 1998/04/14 22:10:50 hubbe Exp $
  */
 #ifndef PROGRAM_H
 #define PROGRAM_H
@@ -360,6 +360,8 @@ struct program *program_from_svalue(struct svalue *s);
 struct find_child_cache_s;
 int find_child(struct program *parent, struct program *child);
 void yywarning(char *fmt, ...) ATTRIBUTE((format(printf,1,2)));
+struct implements_cache_s;
+int implements(struct program *a, struct program *b);
 /* Prototypes end here */