From aa73fc3cd9b4a5fb8ee6244630671143c02c99b0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 21 Oct 1999 14:34:37 -0700
Subject: [PATCH] some bugfixes for AUTO_BIGNUM

Rev: lib/master.pike.in:1.64
Rev: src/builtin_functions.c:1.190
Rev: src/interpret.h:1.34
Rev: src/program.c:1.161
Rev: src/program.h:1.61
Rev: src/svalue.c:1.49
Rev: src/testsuite.in:1.202
---
 lib/master.pike.in      |   8 +++-
 src/builtin_functions.c |  54 ++++++++++------------
 src/interpret.h         |   8 +++-
 src/program.c           |   7 ++-
 src/program.h           |   6 ++-
 src/svalue.c            | 100 ++++++++++++++++++++++++++++++----------
 src/testsuite.in        |   4 +-
 7 files changed, 126 insertions(+), 61 deletions(-)

diff --git a/lib/master.pike.in b/lib/master.pike.in
index ec781388f5..7b20b95d99 100644
--- a/lib/master.pike.in
+++ b/lib/master.pike.in
@@ -1,4 +1,4 @@
-/* $Id: master.pike.in,v 1.63 1999/10/16 04:03:16 hubbe Exp $
+/* $Id: master.pike.in,v 1.64 1999/10/21 21:34:14 hubbe Exp $
  * 
  * Master-file for Pike.
  *
@@ -369,7 +369,11 @@ void handle_error(mixed *trace)
   })
   {
     werror("Error in handle_error in master object:\n");
-    werror("%O\nOriginal error:\n%O\n",x,trace);
+    if(catch {	
+      werror("%O\nOriginal error:\n%O\n",x,trace);
+    }) {
+      werror("sprintf() failed to write error.\n");
+    }
   }
   
 }
diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index a992e17fef..ef853b5572 100644
--- a/src/builtin_functions.c
+++ b/src/builtin_functions.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: builtin_functions.c,v 1.189 1999/10/21 11:16:42 noring Exp $");
+RCSID("$Id: builtin_functions.c,v 1.190 1999/10/21 21:34:31 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "pike_macros.h"
@@ -2053,34 +2053,30 @@ void f_gc(INT32 args)
 #endif
 
 #ifdef AUTO_BIGNUM
-#define TYPEP(ID,NAME,TYPE,TYPE_NAME)                                      \
-void ID(INT32 args)                                                        \
-{                                                                          \
-  int t;                                                                   \
-  if(args<1)                                                               \
-    SIMPLE_TOO_FEW_ARGS_ERROR(NAME, 1);                                    \
-  if(sp[-args].type == T_OBJECT)                                           \
-  {                                                                        \
-    pop_n_elems(args-1);                                                   \
-    args = 1;                                                              \
-    stack_dup();                                                           \
-    push_constant_text("_is_type");                                        \
-    f_index(2);                                                            \
-    if(sp[-1].type == T_FUNCTION || sp[-1].type == T_OBJECT)               \
-    {                                                                      \
-      struct svalue val;                                                   \
-      push_constant_text(TYPE_NAME);                                       \
-      apply_svalue(&sp[-2], 1);                                            \
-      val = *--sp;                                                         \
-      pop_n_elems(2);                                                      \
-      *sp++ = val;                                                         \
-      return;                                                              \
-    }                                                                      \
-    pop_stack();                                                           \
-  }                                                                        \
-  t=sp[-args].type == TYPE;                                                \
-  pop_n_elems(args);                                                       \
-  push_int(t);                                                             \
+/* This should probably be here weather AUTO_BIGNUM is defined or not,
+ * but it can wait a little. /Hubbe
+ */
+
+#define TYPEP(ID,NAME,TYPE,TYPE_NAME)				\
+void ID(INT32 args)						\
+{								\
+  int t;							\
+  if(args<1)							\
+    SIMPLE_TOO_FEW_ARGS_ERROR(NAME, 1);				\
+  if(sp[-args].type == T_OBJECT && sp[-args].u.object->prog)	\
+  {								\
+    int fun=FIND_LFUN(sp[-args].u.object->prog,LFUN__IS_TYPE);	\
+    if(fun != -1)						\
+    {								\
+      push_constant_text(TYPE_NAME);				\
+      apply_low(sp[-args-1].u.object,fun,1);			\
+      stack_unlink(args);					\
+      return;							\
+    }								\
+  }								\
+  t=sp[-args].type == TYPE;					\
+  pop_n_elems(args);						\
+  push_int(t);							\
 }
 #else
 #define TYPEP(ID,NAME,TYPE) \
diff --git a/src/interpret.h b/src/interpret.h
index f833f90e87..4d4b77ffdc 100644
--- a/src/interpret.h
+++ b/src/interpret.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: interpret.h,v 1.33 1999/07/29 17:10:23 mirar Exp $
+ * $Id: interpret.h,v 1.34 1999/10/21 21:34:32 hubbe Exp $
  */
 #ifndef INTERPRET_H
 #define INTERPRET_H
@@ -99,6 +99,12 @@ struct pike_frame
 #define stack_dup() push_svalue(sp-1)
 #define stack_swap() do { struct svalue _=sp[-1]; sp[-1]=sp[-2]; sp[-2]=_; } while(0)
 
+/* This pops a number of arguments from the stack but keeps the top
+ * element on top. Used for popping the arguments while keeping the
+ * return value.
+ */
+#define stack_unlink(X) do { if(X) { free_svalue(sp-(X)-1); sp[-(X)-1]=sp[-1]; sp--; pop_n_elems(X-1); } }while(0)
+
 #define free_pike_frame(F) do{ struct pike_frame *f_=(F); debug_malloc_touch(f_); if(!--f_->refs) really_free_pike_frame(f_); }while(0)
 
 #define POP_PIKE_FRAME() do {						\
diff --git a/src/program.c b/src/program.c
index f111c0ad25..118b2e3c3b 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.160 1999/10/19 15:31:21 hubbe Exp $");
+RCSID("$Id: program.c,v 1.161 1999/10/21 21:34:33 hubbe Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -100,6 +100,8 @@ char *lfun_names[] = {
   "``/",
   "``%",
   "`+=",
+  "_is_type",
+  "_sprintf",
 };
 
 struct program *first_program = 0;
@@ -2920,6 +2922,9 @@ void gc_check_all_programs(void)
   for(p=first_program;p;p=p->next)
   {
     int e;
+
+    dmalloc_touch(p);
+
     for(e=0;e<p->num_constants;e++)
       debug_gc_check_svalues(& p->constants[e].sval, 1, T_PROGRAM, p);
 
diff --git a/src/program.h b/src/program.h
index e5bad42195..896a05f0ad 100644
--- a/src/program.h
+++ b/src/program.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: program.h,v 1.60 1999/09/28 21:57:49 hubbe Exp $
+ * $Id: program.h,v 1.61 1999/10/21 21:34:35 hubbe Exp $
  */
 #ifndef PROGRAM_H
 #define PROGRAM_H
@@ -62,8 +62,10 @@
 #define LFUN_RDIVIDE 36
 #define LFUN_RMOD 37
 #define LFUN_ADD_EQ 38
+#define LFUN__IS_TYPE 39
+#define LFUN__SPRINTF 40
 
-#define NUM_LFUNS 39
+#define NUM_LFUNS 41
 
 extern char *lfun_names[];
 
diff --git a/src/svalue.c b/src/svalue.c
index 8285cea424..93dfb9f6fb 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -23,7 +23,7 @@
 #include "queue.h"
 #include "bignum.h"
 
-RCSID("$Id: svalue.c,v 1.48 1999/10/21 14:55:17 mirar Exp $");
+RCSID("$Id: svalue.c,v 1.49 1999/10/21 21:34:36 hubbe Exp $");
 
 struct svalue dest_ob_zero = { T_INT, 0 };
 
@@ -840,38 +840,88 @@ void describe_svalue(struct svalue *s,int indent,struct processing *p)
       break;
 
     case T_OBJECT:
-      /* FIXME: Check that the stack and reference operations are correct. */
-      ref_push_object(s->u.object);
-      push_constant_text("_sprintf");
-      f_index(2);
-      if(sp[-1].type == T_FUNCTION || sp[-1].type == T_OBJECT)
+      if(s->u.object->prog)
       {
-	push_int('O');
-	f_aggregate_mapping(0);					      
-	apply_svalue(sp-3, 2);   /* FIXME: lfun optimisation? */
-
-	if(!IS_ZERO(sp-1))
+	int fun=FIND_LFUN(s->u.object->prog, LFUN__SPRINTF);
+	if(fun != -1)
 	{
-	   struct pike_string *str;
-	   int i;
-	   if(sp[-1].type != T_STRING)
-	   {
+	  /* We require some tricky coding to make this work
+	   * with tracing...
+	   */
+	  int save_t_flag=t_flag;
+	  string save_buffer=complex_free_buf();
+
+	  t_flag=0;
+	  
+
+	  push_int('O');
+	  f_aggregate_mapping(0);					      
+	  safe_apply_low(s->u.object, fun ,2);
+
+	  if(!IS_ZERO(sp-1))
+	  {
+	    struct pike_string *str;
+	    int i;
+	    if(sp[-1].type != T_STRING)
+	    {
 	      pop_stack();
 	      push_text("(object returned illegal value from _sprintf)");
-	   }
-	   str=sp[-1].u.string;
+	    }
 
-	   /* FIXME: Is this the way to copy a string? /Noring */
-	   for(i = 0; i < str->len; i++)
-	      my_putchar(INDEX_CHARP(str->str, i, str->size_shift));
+	    init_buf_with_string(save_buffer);
+	    t_flag=save_t_flag;
 
-	   pop_n_elems(2); 
-	   break;
-	}
+	    str=sp[-1].u.string;
+	    
+	    switch(str->size_shift)
+	    {
+	      case 0:
+		my_binary_strcat(STR0(str), str->len);
+		break;
 
-	pop_stack();
+	      case 1:
+	      {
+		p_wchar1 *cp=STR1(str);
+		for(i=0;i<str->len;i++)
+		{
+		  int c=cp[i];
+		  if(c<256) 
+		    my_putchar(c);
+		  else
+		  {
+		    sprintf(buf,"<%d>",c);
+		    my_strcat(buf);
+		  }
+		}
+		  break;
+	      }
+
+	      case 2:
+	      {
+		p_wchar2 *cp=STR2(str);
+		for(i=0;i<str->len;i++)
+		{
+		  int c=cp[i];
+		  if(c<256) 
+		    my_putchar(c);
+		  else
+		  {
+		    sprintf(buf,"<%d>",c);
+		    my_strcat(buf);
+		  }
+		}
+		break;
+	      }
+	    }
+	    pop_stack();
+	    break;
+	  }
+
+	  init_buf_with_string(save_buffer);
+	  t_flag=save_t_flag;
+	  pop_stack();
+	}
       }
-      pop_stack();
       
       my_strcat("object");
       break;
diff --git a/src/testsuite.in b/src/testsuite.in
index f804eca3ea..ef0a1753fa 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,4 +1,4 @@
-test_true([["$Id: testsuite.in,v 1.201 1999/10/10 00:49:13 noring Exp $"]])
+test_true([["$Id: testsuite.in,v 1.202 1999/10/21 21:34:37 hubbe Exp $"]])
 
 cond([[all_constants()->_verify_internals]],
 [[
@@ -55,6 +55,8 @@ test_any([[ int a,b; [ [a],b]=({ ({ 1 }) ,2}); return a]],1)
 test_any([[ int a,b; [ [a],b]=({ ({ 1 }) ,2}); return b]],2)
 test_any([[ int a; catch { [a]=({1,2}); }; return 1]],1)
 test_any([[ int a,b; catch { [a,b]=({1}); }; return 1]],1)
+test_any([[ mapping m=([]); m[m]=m; return stringp(sprintf("%O",m)); ]],1)
+
 test_compile_error([[ 
   array a;
   a = path_info[..(sizeof(path_info)-2]*"/";
-- 
GitLab