From a005ebff5e9329e44e22f3fb5459755feea50c8c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 4 Mar 1999 18:15:04 -0800
Subject: [PATCH] prog::`[] should now work..

Rev: src/language.yacc:1.113
Rev: src/object.c:1.59
Rev: src/operators.c:1.50
Rev: src/pike_memory.c:1.33
Rev: src/program.c:1.114
---
 src/language.yacc |  9 +++--
 src/object.c      | 76 +++++++++++++++++++++++-----------------
 src/operators.c   | 10 +++---
 src/pike_memory.c |  3 +-
 src/program.c     | 88 ++++++++++++++++++++++++++++++++---------------
 5 files changed, 118 insertions(+), 68 deletions(-)

diff --git a/src/language.yacc b/src/language.yacc
index 4e438d10ca..eeea008fb8 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -181,7 +181,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.112 1999/03/04 06:04:59 hubbe Exp $");
+RCSID("$Id: language.yacc,v 1.113 1999/03/05 02:14:57 hubbe Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
@@ -1722,6 +1722,7 @@ low_idents: F_IDENTIFIER
 
     $$=reference_inherited_identifier($1->u.sval.u.string,
 				     $3->u.sval.u.string);
+
     if (!$$)
     {
       my_yyerror("Undefined identifier %s::%s", 
@@ -1760,12 +1761,14 @@ low_idents: F_IDENTIFIER
 	if(ISCONSTSTR($2->u.sval.u.string,"`->") ||
 	   ISCONSTSTR($2->u.sval.u.string,"`[]") )
 	{
-	  $$=mkapplynode(mkprgnode(magic_index_program),mkintnode(0));
+	  $$=mkapplynode(mkprgnode(magic_index_program),
+			 mknode(F_ARG_LIST,mkintnode(0),mkintnode(0)));
 	}
 	else if(ISCONSTSTR($2->u.sval.u.string,"`->=") ||
 		ISCONSTSTR($2->u.sval.u.string,"`[]=") )
 	{
-	  $$=mkapplynode(mkprgnode(magic_set_index_program),mkintnode(0));
+	  $$=mkapplynode(mkprgnode(magic_set_index_program),
+			 mknode(F_ARG_LIST,mkintnode(0),mkintnode(0)));
 	}
 	else
 	{
diff --git a/src/object.c b/src/object.c
index dc1e68532c..3c04b49360 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.58 1999/03/04 06:05:06 hubbe Exp $");
+RCSID("$Id: object.c,v 1.59 1999/03/05 02:14:59 hubbe Exp $");
 #include "object.h"
 #include "dynamic_buffer.h"
 #include "interpret.h"
@@ -1169,7 +1169,7 @@ void count_memory_in_objects(INT32 *num_, INT32 *size_)
 
 struct magic_index_struct
 {
-  short inherit_no;
+  struct inherit *inherit;
   struct object *o;
 };
 
@@ -1180,42 +1180,63 @@ struct program *magic_set_index_program=0;
 
 static void f_magic_index_create(INT32 args)
 {
+  struct inherit *inherit;
   struct object *o;
-  int inherit_no;
+  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",&inherit_no);
+  get_all_args("create",args,"%i%i",&inherit_no,&parent_level);
 
   o=fp->next->current_object;
   if(!o) error("Illegal magic index call.\n");
 
+  
+  inherit=INHERIT_FROM_INT(o->prog, fp->next->fun);
+
+  while(parent_level--)
+  {
+    int i;
+    if(inherit->parent_offset)
+    {
+      i=o->parent_identifier;
+      o=o->parent;
+      parent_level+=inherit->parent_offset-1;
+    }else{
+      i=inherit->parent_identifier;
+      o=inherit->parent;
+    }
+    
+    if(!o)
+      error("Parent was lost!\n");
+    
+    if(!(p=o->prog))
+      error("Attempting to access variable in destructed object\n");
+    
+    inherit=INHERIT_FROM_INT(p, i);
+  }
+
   add_ref(MAGIC_THIS->o=o);
-  MAGIC_THIS->inherit_no=inherit_no;
+  MAGIC_THIS->inherit = inherit + inherit_no;
 }
 
 static void f_magic_index(INT32 args)
 {
-  int f,inherit_no;
+  struct inherit *inherit;
+  int f;
   struct pike_string *s;
   struct object *o;
-  struct program *p;
 
   get_all_args("::`->",args,"%S",&s);
 
   if(!(o=MAGIC_THIS->o))
     error("Magic index error\n");
 
-  if(!(p=o->prog))
-    error("Indexing a destructed object!\n");
-
-  inherit_no=MAGIC_THIS->inherit_no;
+  inherit=MAGIC_THIS->inherit;
 
-  if(inherit_no >= p->num_inherits || inherit_no < 0)
-    error("Bad magic index (inherit_no=%d p->num_inherits=%d)!\n",inherit_no,p->num_inherits);
-
-  f=find_shared_string_identifier(s,p->inherits[inherit_no].prog);
+  f=find_shared_string_identifier(s,inherit->prog);
 
   if(f<0)
   {
@@ -1225,7 +1246,7 @@ static void f_magic_index(INT32 args)
   }else{
     struct svalue sval;
     low_object_index_no_free(&sval,o,f+
-			     p->inherits[inherit_no].identifier_level);
+			     inherit->identifier_level);
     pop_stack();
     *sp=sval;
     sp++;
@@ -1234,33 +1255,26 @@ static void f_magic_index(INT32 args)
 
 static void f_magic_set_index(INT32 args)
 {
-  int f,inherit_no;
+  int f;
   struct pike_string *s;
   struct object *o;
-  struct program *p;
   struct svalue *val;
+  struct inherit *inherit;
 
   get_all_args("::`->=",args,"%S%*",&s,&val);
 
   if(!(o=MAGIC_THIS->o))
     error("Magic index error\n");
 
-  if(!(p=o->prog))
-    error("Indexing a destructed object!\n");
-
-  inherit_no=MAGIC_THIS->inherit_no;
-
-  if(inherit_no >= p->num_inherits || inherit_no < 0)
-    error("Bad magic index!\n");
+  inherit=MAGIC_THIS->inherit;
 
-  f=find_shared_string_identifier(s,p->inherits[inherit_no].prog);
+  f=find_shared_string_identifier(s,inherit->prog);
 
   if(f<0)
   {
     error("No such variable in object.\n");
   }else{
-    object_low_set_index(o, f+
-			 p->inherits[inherit_no].identifier_level,
+    object_low_set_index(o, f+inherit->identifier_level,
 			 val);
     pop_n_elems(args);
     push_int(0);
@@ -1276,15 +1290,15 @@ 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:void)",0);
+  add_function("create",f_magic_index_create,"function(int,int:void)",0);
   magic_index_program=end_program();
 
   start_new_program();
   offset=ADD_STORAGE(struct magic_index_struct);
   map_variable("__obj","object",ID_STATIC,
 	       offset  + OFFSETOF(magic_index_struct, o), T_OBJECT);
-  add_function("`()",f_magic_index,"function(string,mixed:void)",0);
-  add_function("create",f_magic_index_create,"function(int:void)",0);
+  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/operators.c b/src/operators.c
index 43f67b2a0b..4641bb88b4 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -5,7 +5,7 @@
 \*/
 #include "global.h"
 #include <math.h>
-RCSID("$Id: operators.c,v 1.49 1999/03/02 03:22:13 hubbe Exp $");
+RCSID("$Id: operators.c,v 1.50 1999/03/05 02:15:01 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "multiset.h"
@@ -884,8 +884,8 @@ void o_or(void)
   case T_ARRAY:
   {
     struct array *a;
-    a=merge_array_without_order(sp[-2].u.array, sp[-1].u.array, PIKE_ARRAY_OP_OR);
-    pop_n_elems(2);
+    a=merge_array_without_order2(sp[-2].u.array, sp[-1].u.array, PIKE_ARRAY_OP_OR);
+    sp-=2; /* Refs are eaten by function above */
     push_array(a);
     return;
   }
@@ -974,8 +974,8 @@ void o_xor(void)
   case T_ARRAY:
   {
     struct array *a;
-    a=merge_array_without_order(sp[-2].u.array, sp[-1].u.array, PIKE_ARRAY_OP_XOR);
-    pop_n_elems(2);
+    a=merge_array_without_order2(sp[-2].u.array, sp[-1].u.array, PIKE_ARRAY_OP_XOR);
+    sp-=2; /* Refs are eaten by function above */
     push_array(a);
     return;
   }
diff --git a/src/pike_memory.c b/src/pike_memory.c
index f97fa4f3ce..6600c7b1d2 100644
--- a/src/pike_memory.c
+++ b/src/pike_memory.c
@@ -10,7 +10,7 @@
 #include "pike_macros.h"
 #include "gc.h"
 
-RCSID("$Id: pike_memory.c,v 1.32 1999/02/27 21:27:00 grubba Exp $");
+RCSID("$Id: pike_memory.c,v 1.33 1999/03/05 02:15:02 hubbe Exp $");
 
 /* strdup() is used by several modules, so let's provide it */
 #ifndef HAVE_STRDUP
@@ -894,6 +894,7 @@ static void add_location(struct memhdr *mh, int locnum)
   if(!ml)
   {
     ml=alloc_memloc();
+    ml->times=0;
     ml->locnum=locnum;
     ml->next=mh->locations;
     ml->mh=mh;
diff --git a/src/program.c b/src/program.c
index 2a5fedac38..439fcc498d 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.113 1999/03/04 06:05:09 hubbe Exp $");
+RCSID("$Id: program.c,v 1.114 1999/03/05 02:15:04 hubbe Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -1077,19 +1077,22 @@ int low_reference_inherited_identifier(struct program_state *q,
   return np->num_identifier_references -1;
 }
 
-static int middle_reference_inherited_identifier(
-  struct program_state *state,
-  struct pike_string *super_name,
-  struct pike_string *function_name)
+node *reference_inherited_identifier(struct pike_string *super_name,
+				   struct pike_string *function_name)
 {
-  int e,i;
-  struct program *p=state?state->new_program:new_program;
+  int n,e,id;
+  struct program_state *state=previous_program_state;
+
+  struct program *p;
+
 
 #ifdef PIKE_DEBUG
   if(function_name!=debug_findstring(function_name))
     fatal("reference_inherited_function on nonshared string.\n");
 #endif
-  
+
+  p=new_program;
+
   for(e=p->num_inherits-1;e>0;e--)
   {
     if(p->inherits[e].inherit_level!=1) continue;
@@ -1099,30 +1102,59 @@ static int middle_reference_inherited_identifier(
       if(super_name != p->inherits[e].name)
 	continue;
 
-    i=low_reference_inherited_identifier(state,e,function_name);
-    if(i==-1) continue;
-    return i;
-  }
-  return -1;
-}
+    id=low_reference_inherited_identifier(0,e,function_name);
 
-node *reference_inherited_identifier(struct pike_string *super_name,
-				   struct pike_string *function_name)
-{
-  int i,n;
-  struct program_state *p=previous_program_state;
+    if(id!=-1)
+      return mkidentifiernode(id);
 
-  i=middle_reference_inherited_identifier(0,
-					  super_name,
-					  function_name);
-  if(i!=-1) return mkidentifiernode(i);
+    if(ISCONSTSTR(function_name,"`->") ||
+       ISCONSTSTR(function_name,"`[]"))
+    {
+      return mkapplynode(mkprgnode(magic_index_program),
+			 mknode(F_ARG_LIST,mkintnode(e),mkintnode(0)));
+    }
 
-  for(n=0;n<compilation_depth;n++,p=p->previous)
+    if(ISCONSTSTR(function_name,"`->=") ||
+       ISCONSTSTR(function_name,"`[]="))
+    {
+      return mkapplynode(mkprgnode(magic_set_index_program),
+			 mknode(F_ARG_LIST,mkintnode(e),mkintnode(0)));
+    }
+  }
+
+
+  for(n=0;n<compilation_depth;n++,state=state->previous)
   {
-    i=middle_reference_inherited_identifier(p,super_name,
-					    function_name);
-    if(i!=-1)
-      return mkexternalnode(n,i,ID_FROM_INT(p->new_program, i));
+    struct program *p=state->new_program;
+    
+    for(e=p->num_inherits-1;e>0;e--)
+    {
+      if(p->inherits[e].inherit_level!=1) continue;
+      if(!p->inherits[e].name) continue;
+      
+      if(super_name)
+	if(super_name != p->inherits[e].name)
+	  continue;
+      
+      id=low_reference_inherited_identifier(state,e,function_name);
+
+      if(id!=-1)
+	return mkexternalnode(n,id,ID_FROM_INT(state->new_program, id));
+
+      if(ISCONSTSTR(function_name,"`->") ||
+	 ISCONSTSTR(function_name,"`[]"))
+      {
+	return mkapplynode(mkprgnode(magic_index_program),
+			   mknode(F_ARG_LIST,mkintnode(e),mkintnode(n+1)));
+      }
+      
+      if(ISCONSTSTR(function_name,"`->=") ||
+	 ISCONSTSTR(function_name,"`[]="))
+      {
+	return mkapplynode(mkprgnode(magic_set_index_program),
+			   mknode(F_ARG_LIST,mkintnode(e),mkintnode(n+1)));
+      }
+    }
   }
 
   return 0;
-- 
GitLab