diff --git a/src/docode.c b/src/docode.c
index 0fecbb09ee1039a020e6a9e6db462f238b899c0d..1bad0e9152db3295bc4ea6e0d02efdf567856726 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.44 1999/02/10 01:29:05 hubbe Exp $");
+RCSID("$Id: docode.c,v 1.45 1999/03/11 13:44:27 hubbe Exp $");
 #include "las.h"
 #include "program.h"
 #include "language.h"
@@ -237,6 +237,12 @@ static int do_docode2(node *n,int flags)
 
   switch(n->token)
   {
+  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);
+    return 1;
+      
   case F_EXTERNAL:
     emit(F_LDA, n->u.integer.a);
     if(flags & WANT_LVALUE)
diff --git a/src/interpreter.h b/src/interpreter.h
index e7f04813cb3ca567d8a857f4061892dfc8157219..6a1c7130acaa400738fafe3c2879ffa5246c9cb0 100644
--- a/src/interpreter.h
+++ b/src/interpreter.h
@@ -1184,6 +1184,14 @@ static int eval_instruction(unsigned char *pc)
       print_return_value();
       break;
 
+      CASE(F_MAGIC_INDEX);
+      push_magic_index(magic_index_program, accumulator, GET_ARG());
+      break;
+
+      CASE(F_MAGIC_SET_INDEX);
+      push_magic_index(magic_set_index_program, accumulator, GET_ARG());
+      break;
+
       CASE(F_CAST); f_cast(); break;
 
       CASE(F_RANGE); o_range(); break;
diff --git a/src/language.yacc b/src/language.yacc
index eeea008fb8e87d08486524241a1ba5bae3f0300b..b150e9c2a3a4bfc37b8fe8445aab8b84b17807cb 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -31,7 +31,7 @@
 
 %token F_INDEX F_ARROW F_INDIRECT F_STRING_INDEX F_LOCAL_INDEX
 %token F_LOCAL_LOCAL_INDEX F_LOCAL_ARROW F_GLOBAL_LOCAL_INDEX
-%token F_POS_INT_INDEX F_NEG_INT_INDEX
+%token F_POS_INT_INDEX F_NEG_INT_INDEX F_MAGIC_INDEX F_MAGIC_SET_INDEX
 %token F_LTOSVAL F_LTOSVAL2
 %token F_PUSH_ARRAY 
 %token F_RANGE F_COPY_VALUE
@@ -181,7 +181,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.113 1999/03/05 02:14:57 hubbe Exp $");
+RCSID("$Id: language.yacc,v 1.114 1999/03/11 13:44:30 hubbe Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
@@ -1761,14 +1761,12 @@ low_idents: F_IDENTIFIER
 	if(ISCONSTSTR($2->u.sval.u.string,"`->") ||
 	   ISCONSTSTR($2->u.sval.u.string,"`[]") )
 	{
-	  $$=mkapplynode(mkprgnode(magic_index_program),
-			 mknode(F_ARG_LIST,mkintnode(0),mkintnode(0)));
+	  $$=mknode(F_MAGIC_INDEX,mkintnode(0),mkintnode(0));
 	}
 	else if(ISCONSTSTR($2->u.sval.u.string,"`->=") ||
 		ISCONSTSTR($2->u.sval.u.string,"`[]=") )
 	{
-	  $$=mkapplynode(mkprgnode(magic_set_index_program),
-			 mknode(F_ARG_LIST,mkintnode(0),mkintnode(0)));
+	  $$=mknode(F_MAGIC_SET_INDEX,mkintnode(0),mkintnode(0));
 	}
 	else
 	{
diff --git a/src/lex.c b/src/lex.c
index 80303958ebbc895a3dc8d580f9bc9360de3bcab7..f8ccb47d309541e0cc052dafb0cf506682530b22 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: lex.c,v 1.63 1999/02/20 17:47:02 grubba Exp $");
+RCSID("$Id: lex.c,v 1.64 1999/03/11 13:44:32 hubbe Exp $");
 #include "language.h"
 #include "array.h"
 #include "lex.h"
@@ -246,6 +246,8 @@ struct keyword instr_names[]=
 { "global=local;",      F_LOCAL_2_GLOBAL, I_HASARG },
 { "local->x",           F_LOCAL_ARROW, I_HASARG },
 { "global[local]",      F_GLOBAL_LOCAL_INDEX, I_HASARG },
+{ "::`[]",              F_MAGIC_INDEX, I_HASARG },
+{ "::`[]=",             F_MAGIC_SET_INDEX, I_HASARG },
 };
 
 struct instr instrs[F_MAX_INSTR - F_OFFSET];
diff --git a/src/object.c b/src/object.c
index 3c04b493602d0667fbc50e49d12d36fad7093596..ec954c8c035c915828cd6938f6d8e67513688792 100644
--- a/src/object.c
+++ b/src/object.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: object.c,v 1.59 1999/03/05 02:14:59 hubbe Exp $");
+RCSID("$Id: object.c,v 1.60 1999/03/11 13:44:33 hubbe Exp $");
 #include "object.h"
 #include "dynamic_buffer.h"
 #include "interpret.h"
@@ -1174,27 +1174,21 @@ struct magic_index_struct
 };
 
 #define MAGIC_THIS ((struct magic_index_struct *)(fp->current_storage))
+#define MAGIC_O2S(o) ((struct magic_index_struct *)&(o->storage))
 
 struct program *magic_index_program=0;
 struct program *magic_set_index_program=0;
 
-static void f_magic_index_create(INT32 args)
+void push_magic_index(struct program *type, int inherit_no, int parent_level)
 {
   struct inherit *inherit;
-  struct object *o;
+  struct object *o,*magic;
   struct program *p;
-  int inherit_no,parent_level;
-
-  if(MAGIC_THIS->o)
-    error("Cannot call this function twice.\n");
-
-  get_all_args("create",args,"%i%i",&inherit_no,&parent_level);
 
-  o=fp->next->current_object;
+  o=fp->current_object;
   if(!o) error("Illegal magic index call.\n");
-
   
-  inherit=INHERIT_FROM_INT(o->prog, fp->next->fun);
+  inherit=INHERIT_FROM_INT(o->prog, fp->fun);
 
   while(parent_level--)
   {
@@ -1218,8 +1212,11 @@ static void f_magic_index_create(INT32 args)
     inherit=INHERIT_FROM_INT(p, i);
   }
 
-  add_ref(MAGIC_THIS->o=o);
-  MAGIC_THIS->inherit = inherit + inherit_no;
+
+  magic=low_clone(type);
+  add_ref(MAGIC_O2S(magic)->o=o);
+  MAGIC_O2S(magic)->inherit = inherit + inherit_no;
+  push_object(magic);
 }
 
 static void f_magic_index(INT32 args)
@@ -1290,7 +1287,6 @@ void init_object(void)
   map_variable("__obj","object",ID_STATIC,
 	       offset  + OFFSETOF(magic_index_struct, o), T_OBJECT);
   add_function("`()",f_magic_index,"function(string:mixed)",0);
-  add_function("create",f_magic_index_create,"function(int,int:void)",0);
   magic_index_program=end_program();
 
   start_new_program();
@@ -1298,7 +1294,6 @@ void init_object(void)
   map_variable("__obj","object",ID_STATIC,
 	       offset  + OFFSETOF(magic_index_struct, o), T_OBJECT);
   add_function("`()",f_magic_set_index,"function(string,mixed:void)",0);
-  add_function("create",f_magic_index_create,"function(int,int:void)",0);
   magic_set_index_program=end_program();
 }
 
diff --git a/src/object.h b/src/object.h
index df973883e99dc63fa3649fda1e57f43b12a3a569..d72d996b7a5c05659b47b29c22227b3fc8c509d6 100644
--- a/src/object.h
+++ b/src/object.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: object.h,v 1.24 1999/03/04 06:05:08 hubbe Exp $
+ * $Id: object.h,v 1.25 1999/03/11 13:44:35 hubbe Exp $
  */
 #ifndef OBJECT_H
 #define OBJECT_H
@@ -92,6 +92,7 @@ void gc_mark_all_objects(void);
 void gc_free_all_unreferenced_objects(void);
 void count_memory_in_objects(INT32 *num_, INT32 *size_);
 struct magic_index_struct;
+void push_magic_index(struct program *type, int inherit_no, int parent_level);
 void init_object(void);
 void exit_object(void);
 /* Prototypes end here */
diff --git a/src/pike_memory.h b/src/pike_memory.h
index 142079081f0a99a30b433c4c70cda8f20ad0b9c0..c12077c7841b2e0e6cb8bc12b8b016579177ce5d 100644
--- a/src/pike_memory.h
+++ b/src/pike_memory.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: pike_memory.h,v 1.10 1999/03/10 02:41:18 hubbe Exp $
+ * $Id: pike_memory.h,v 1.11 1999/03/11 13:44:36 hubbe Exp $
  */
 #ifndef MEMORY_H
 #define MEMORY_H
@@ -60,7 +60,6 @@ struct generic_mem_searcher
 #define MEMCHR0 MEMCHR
 
 /* Prototypes begin here */
-char *strdup(const char *str);
 int pcharp_memcmp(PCHARP a, PCHARP b, int sz);
 INLINE p_wchar1 *MEMCHR1(p_wchar1 *p,p_wchar1 c,INT32 e);
 INLINE p_wchar2 *MEMCHR2(p_wchar2 *p,p_wchar2 c,INT32 e);
diff --git a/src/program.c b/src/program.c
index 23e44f24c8dc44860ca1104a0c314781f2ad6b83..15a6825e13befbd202d5f47e8416b2a720492e9a 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.115 1999/03/07 18:34:28 grubba Exp $");
+RCSID("$Id: program.c,v 1.116 1999/03/11 13:44:38 hubbe Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -1110,15 +1110,13 @@ node *reference_inherited_identifier(struct pike_string *super_name,
     if(ISCONSTSTR(function_name,"`->") ||
        ISCONSTSTR(function_name,"`[]"))
     {
-      return mkapplynode(mkprgnode(magic_index_program),
-			 mknode(F_ARG_LIST,mkintnode(e),mkintnode(0)));
+      return mknode(F_MAGIC_INDEX,mkintnode(e),mkintnode(0));
     }
 
     if(ISCONSTSTR(function_name,"`->=") ||
        ISCONSTSTR(function_name,"`[]="))
     {
-      return mkapplynode(mkprgnode(magic_set_index_program),
-			 mknode(F_ARG_LIST,mkintnode(e),mkintnode(0)));
+      return mknode(F_MAGIC_SET_INDEX,mkintnode(e),mkintnode(0));
     }
   }