From d4828ce85db94e99ea6a8f2323cd102e3e12e068 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 17 Jul 1997 18:44:28 -0700
Subject: [PATCH] bugs fixed

Rev: src/modules/files/file.c:1.48
Rev: src/modules/files/file.h:1.4
Rev: src/modules/files/socket.c:1.12
Rev: src/object.c:1.20
Rev: src/pike_macros.h:1.3
Rev: src/program.c:1.35
Rev: src/program.h:1.16
---
 src/modules/files/file.c   | 40 ++++++++++-------
 src/modules/files/file.h   |  1 -
 src/modules/files/socket.c | 26 ++++++++---
 src/object.c               | 54 ++++++++++++++++------
 src/pike_macros.h          |  1 +
 src/program.c              | 92 +++++++++++++++++++++++++++-----------
 src/program.h              |  2 +
 7 files changed, 152 insertions(+), 64 deletions(-)

diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index 6dae91cd4d..0cb1771971 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -6,7 +6,7 @@
 #define READ_BUFFER 8192
 
 #include "global.h"
-RCSID("$Id: file.c,v 1.47 1997/07/03 02:36:16 grubba Exp $");
+RCSID("$Id: file.c,v 1.48 1997/07/18 01:44:26 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "stralloc.h"
@@ -91,7 +91,6 @@ static void file_write_callback(int fd, void *data);
 static void init_fd(int fd, int open_mode)
 {
   files[fd].refs=1;
-  files[fd].fd=fd;
   files[fd].open_mode=open_mode;
   files[fd].id.type=T_INT;
   files[fd].id.u.integer=0;
@@ -106,16 +105,29 @@ static void init_fd(int fd, int open_mode)
 static int close_fd(int fd)
 {
 #ifdef DEBUG
-  if(fd < 0)
+  if(fd < 0 || fd>=MAX_OPEN_FILEDESCRIPTORS)
     fatal("Bad argument to close_fd()\n");
 
-  if(files[fd].refs<0)
+  if(files[fd].refs<1)
     fatal("Wrong ref count in file struct\n");
 #endif
 
   files[fd].refs--;
   if(!files[fd].refs)
   {
+    set_read_callback(fd,0,0);
+    set_write_callback(fd,0,0);
+
+    free_svalue(& files[fd].id);
+    free_svalue(& files[fd].read_callback);
+    free_svalue(& files[fd].write_callback);
+    free_svalue(& files[fd].close_callback);
+    files[fd].id.type=T_INT;
+    files[fd].read_callback.type=T_INT;
+    files[fd].write_callback.type=T_INT;
+    files[fd].close_callback.type=T_INT;
+    files[fd].open_mode = 0;
+
     while(1)
     {
       int i;
@@ -150,19 +162,6 @@ static int close_fd(int fd)
       }
       break;
     }
-
-    set_read_callback(fd,0,0);
-    set_write_callback(fd,0,0);
-
-    free_svalue(& files[fd].id);
-    free_svalue(& files[fd].read_callback);
-    free_svalue(& files[fd].write_callback);
-    free_svalue(& files[fd].close_callback);
-    files[fd].id.type=T_INT;
-    files[fd].read_callback.type=T_INT;
-    files[fd].write_callback.type=T_INT;
-    files[fd].close_callback.type=T_INT;
-    files[fd].open_mode = 0;
   }
   return 0;
 }
@@ -1098,6 +1097,12 @@ static void exit_file_struct(struct object *o)
   ERRNO=-1;
 }
 
+static void (struct object *o)
+{
+  FD=-1;
+  ERRNO=-1;
+}
+
 static void file_dup(INT32 args)
 {
   struct object *o;
@@ -1534,6 +1539,7 @@ void pike_module_init()
 
   set_init_callback(init_file_struct);
   set_exit_callback(exit_file_struct);
+  set_gc_mark_callback(gc_mark_file_struct);
 
   file_program=end_program();
   add_program_constant("file",file_program,0);
diff --git a/src/modules/files/file.h b/src/modules/files/file.h
index 548c9e9a48..37e6cbbed0 100644
--- a/src/modules/files/file.h
+++ b/src/modules/files/file.h
@@ -26,7 +26,6 @@
 struct my_file
 {
   INT32 refs;
-  int fd;
   short open_mode;
   struct svalue id;
   struct svalue read_callback;
diff --git a/src/modules/files/socket.c b/src/modules/files/socket.c
index 77fc68de74..0b837cc3c0 100644
--- a/src/modules/files/socket.c
+++ b/src/modules/files/socket.c
@@ -56,7 +56,7 @@ struct port
 
 #define THIS ((struct port *)(fp->current_storage))
 
-static void do_close(struct port *p)
+static void do_close(struct port *p, struct object *o)
 {
  retry:
   if(p->fd >= 0)
@@ -65,6 +65,8 @@ static void do_close(struct port *p)
       if(errno == EINTR)
 	goto retry;
 
+    if(query_read_callback(p->fd)==port_accept_callback)
+      o->refs--;
     set_read_callback(p->fd,0,0);
   }
   
@@ -109,7 +111,7 @@ static void port_accept_callback(int fd,void *data)
 static void port_listen_fd(INT32 args)
 {
   int fd;
-  do_close(THIS);
+  do_close(THIS,fp->current_object);
 
   if(args < 1)
     error("Too few arguments to port->bind_fd()\n");
@@ -138,9 +140,12 @@ static void port_listen_fd(INT32 args)
   if(args > 1)
   {
     assign_svalue(& THIS->accept_callback, sp+1-args);
+    set_nonblocking(fd,1);
     if(!IS_ZERO(& THIS->accept_callback))
+    {
+      fp->current_object->refs++;
       set_read_callback(fd, port_accept_callback, (void *)THIS);
-    set_nonblocking(fd,1);
+    }
   }
 
   THIS->fd=fd;
@@ -155,7 +160,7 @@ static void port_bind(INT32 args)
   int o;
   int fd,tmp;
 
-  do_close(THIS);
+  do_close(THIS,fp->current_object);
 
   if(args < 1)
     error("Too few arguments to port->bind()\n");
@@ -221,7 +226,10 @@ static void port_bind(INT32 args)
   {
     assign_svalue(& THIS->accept_callback, sp+1-args);
     if(!IS_ZERO(& THIS->accept_callback))
+    {
+      fp->current_object->refs++;
       set_read_callback(fd, port_accept_callback, (void *)THIS);
+    }
     set_nonblocking(fd,1);
   }
 
@@ -256,7 +264,10 @@ static void port_create(INT32 args)
 	{
 	  assign_svalue(& THIS->accept_callback, sp+1-args);
 	  if(!IS_ZERO(& THIS->accept_callback))
+	  {
+	    fp->current_object->refs++;
 	    set_read_callback(THIS->fd, port_accept_callback, (void *)THIS);
+	  }
 	  set_nonblocking(THIS->fd,1);
 	}
       }
@@ -348,7 +359,7 @@ static void init_port_struct(struct object *o)
 
 static void exit_port_struct(struct object *o)
 {
-  do_close(THIS);
+  do_close(THIS,o);
   free_svalue(& THIS->id);
   free_svalue(& THIS->accept_callback);
   THIS->id.type=T_INT;
@@ -357,8 +368,11 @@ static void exit_port_struct(struct object *o)
 
 void port_setup_program()
 {
+  INT32 offset;
   start_new_program();
-  add_storage(sizeof(struct port));
+  offset=add_storage(sizeof(struct port));
+  map_variable("_accept_callback","mixed",offset+OFFSETOF(port,accept_callback),T_MIXED);
+  map_variable("_id","mixed",offset+OFFSETOF(port,id),T_MIXED);
   add_function("bind",port_bind,"function(int,void|mixed:int)",0);
   add_function("listen_fd",port_listen_fd,"function(int,void|mixed:int)",0);
   add_function("set_id",port_set_id,"function(mixed:mixed)",0);
diff --git a/src/object.c b/src/object.c
index 672b75f979..5380ee7ec7 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.19 1997/07/14 18:23:20 hubbe Exp $");
+RCSID("$Id: object.c,v 1.20 1997/07/18 01:44:19 hubbe Exp $");
 #include "object.h"
 #include "dynamic_buffer.h"
 #include "interpret.h"
@@ -766,27 +766,55 @@ void gc_mark_object_as_referenced(struct object *o)
 {
   if(gc_mark(o))
   {
-    if(o->prog)
+    int e;
+    struct frame frame;
+    struct program *p;
+
+    if(!o || !(p=o->prog)) return; /* Object already destructed */
+    o->refs++;
+
+    frame.parent_frame=fp;
+    frame.current_object=o;  /* refs already updated */
+    frame.locals=0;
+    frame.fun=-1;
+    frame.pc=0;
+    fp= & frame;
+
+    for(e=p->num_inherits-1; e>=0; e--)
     {
-      INT32 e;
+      int d;
       
-      for(e=0;e<(int)o->prog->num_identifier_indexes;e++)
+      frame.context=p->inherits[e];
+      frame.context.prog->refs++;
+      frame.current_storage=o->storage+frame.context.storage_offset;
+
+      if(frame.context.prog->gc_marked)
+	frame.context.prog->gc_marked(o);
+
+
+      for(d=0;d<(int)frame.context.prog->num_identifiers;d++)
       {
-	struct identifier *i;
-	
-	i=ID_FROM_INT(o->prog, e);
-	
-	if(!IDENTIFIER_IS_VARIABLE(i->flags)) continue;
+	if(!IDENTIFIER_IS_VARIABLE(frame.context.prog->identifiers[d].flags)) 
+	  continue;
 	
-	if(i->run_time_type == T_MIXED)
+	if(frame.context.prog->identifiers[d].run_time_type == T_MIXED)
 	{
-	  gc_mark_svalues((struct svalue *)LOW_GET_GLOBAL(o,e,i),1);
+	  struct svalue *s;
+	  s=(struct svalue *)(frame.current_storage +
+			      frame.context.prog->identifiers[d].func.offset);
+	  gc_mark_svalues(s,1);
 	}else{
-	  gc_mark_short_svalue((union anything *)LOW_GET_GLOBAL(o,e,i),
-			       i->run_time_type);
+	  union anything *u;
+	  u=(union anything *)(frame.current_storage +
+			       frame.context.prog->identifiers[d].func.offset);
+	  gc_mark_short_svalue(u,frame.context.prog->identifiers[d].run_time_type);
 	}
       }
+      free_program(frame.context.prog);
     }
+    
+    free_object(frame.current_object);
+    fp = frame.parent_frame;
   }
 }
 
diff --git a/src/pike_macros.h b/src/pike_macros.h
index 812a50fc11..b27ba57e72 100644
--- a/src/pike_macros.h
+++ b/src/pike_macros.h
@@ -9,6 +9,7 @@
 #include <sys/param.h>
 #include "pike_memory.h"
 
+#define OFFSETOF(str_type, field) ((long)& (((struct str_type *)0)->field))
 #define BASEOF(ptr, str_type, field)  \
 ((struct str_type *)((char*)ptr - (char*)& (((struct str_type *)0)->field)))
 
diff --git a/src/program.c b/src/program.c
index cd31deb163..e0f9fdaf2a 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.34 1997/06/10 20:02:17 hubbe Exp $");
+RCSID("$Id: program.c,v 1.35 1997/07/18 01:44:22 hubbe Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -695,6 +695,15 @@ void set_exit_callback(void (*exit)(struct object *))
   fake_program.exit=exit;
 }
 
+/*
+ * This callback is called to allow the object to mark all internal
+ * structures as 'used'.
+ */
+void set_gc_mark_callback(void (*m)(struct object *))
+{
+  fake_program.gc_marked=m;
+}
+
 
 int low_reference_inherited_identifier(int e,struct pike_string *name)
 {
@@ -896,6 +905,53 @@ int isidentifier(struct pike_string *s)
   return -1;
 }
 
+int low_define_variable(struct pike_string *name,
+			struct pike_string *type,
+			INT32 flags,
+			INT32 offset,
+			INT32 run_time_type)
+{
+  int n;
+  struct identifier dummy;
+  struct reference ref;
+  
+  copy_shared_string(dummy.name, name);
+  copy_shared_string(dummy.type, type);
+  dummy.flags = 0;
+  dummy.run_time_type=run_time_type;
+  dummy.func.offset=offset;
+  
+  ref.flags=flags;
+  ref.identifier_offset=areas[A_IDENTIFIERS].s.len / sizeof dummy;
+  ref.inherit_offset=0;
+
+  add_to_mem_block(A_IDENTIFIERS, (char *)&dummy, sizeof dummy);
+  fake_program.num_identifiers ++;
+
+  n=areas[A_IDENTIFIER_REFERENCES].s.len / sizeof ref;
+  add_to_mem_block(A_IDENTIFIER_REFERENCES, (char *)&ref, sizeof ref);
+  fake_program.num_identifier_references ++;
+
+  return n;
+}
+
+int map_variable(char *name,
+		 char *type,
+		 INT32 flags,
+		 INT32 offset,
+		 INT32 run_time_type)
+{
+  int ret;
+  struct pike_string *n,*t;
+  n=make_shared_string(name);
+  t=parse_type(type);
+  run_time_type=compile_type_to_runtime_type(t);
+  ret=low_define_variable(n,t,flags,offset,run_time_type);
+  free_string(n);
+  free_string(t);
+  return ret;
+}
+
 /* argument must be a shared string */
 int define_variable(struct pike_string *name,
 		    struct pike_string *type,
@@ -931,32 +987,14 @@ int define_variable(struct pike_string *name,
       my_yyerror("Illegal to redefine inherited variable with different type.");
 
   } else {
-    struct identifier dummy;
-    struct reference ref;
-
-    copy_shared_string(dummy.name, name);
-    copy_shared_string(dummy.type, type);
-    dummy.flags = 0;
-    dummy.run_time_type=compile_type_to_runtime_type(type);
-
-    if(dummy.run_time_type == T_FUNCTION)
-      dummy.run_time_type = T_MIXED;
-
-    dummy.func.offset=add_storage(dummy.run_time_type == T_MIXED ?
-				  sizeof(struct svalue) :
-				  sizeof(union anything));
-
-    ref.flags=flags;
-    ref.identifier_offset=areas[A_IDENTIFIERS].s.len / sizeof dummy;
-    ref.inherit_offset=0;
-
-    add_to_mem_block(A_IDENTIFIERS, (char *)&dummy, sizeof dummy);
-    fake_program.num_identifiers ++;
-
-    n=areas[A_IDENTIFIER_REFERENCES].s.len / sizeof ref;
-    add_to_mem_block(A_IDENTIFIER_REFERENCES, (char *)&ref, sizeof ref);
-    fake_program.num_identifier_references ++;
-
+    int run_time_type=compile_type_to_runtime_type(type);
+    if(run_time_type == T_FUNCTION) run_time_type = T_MIXED;
+    
+    n=low_define_variable(name, type, flags,
+			  add_storage(run_time_type == T_MIXED ?
+				      sizeof(struct svalue) :
+				      sizeof(union anything)),
+			  run_time_type);
   }
 
   return n;
diff --git a/src/program.h b/src/program.h
index 6e2b42c41c..3e59542f3d 100644
--- a/src/program.h
+++ b/src/program.h
@@ -149,6 +149,7 @@ struct program
   char *linenumbers;
   void (*init)(struct object *);
   void (*exit)(struct object *);
+  void (*gc_marked)(struct object *);
 #ifdef DEBUG
   unsigned INT32 checksum;
 #endif
@@ -191,6 +192,7 @@ struct program *end_program();
 SIZE_T add_storage(SIZE_T size);
 void set_init_callback(void (*init)(struct object *));
 void set_exit_callback(void (*exit)(struct object *));
+void set_gc_mark_callback(void (*m)(struct object *));
 int low_reference_inherited_identifier(int e,struct pike_string *name);
 int reference_inherited_identifier(struct pike_string *super_name,
 				   struct pike_string *function_name);
-- 
GitLab