3ad9861997-01-26Fredrik Hübinette (Hubbe) /*\ ||| This file a part of Pike, and is copyright by Fredrik Hubinette ||| Pike is distributed as GPL (General Public License) ||| See the files COPYING and DISCLAIMER for more information. \*/
8108741999-03-07Henrik Grubbström (Grubba) /**/
3ad9861997-01-26Fredrik Hübinette (Hubbe) #include "global.h"
24ddc71998-03-28Henrik Grubbström (Grubba) #include "stralloc.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
3ad9861997-01-26Fredrik Hübinette (Hubbe) #include "object.h" #include "constants.h" #include "interpret.h" #include "svalue.h" #include "mapping.h" #include "array.h" #include "multiset.h" #include "dynamic_buffer.h"
b2d3e42000-12-01Fredrik Hübinette (Hubbe) #include "pike_error.h"
50817d1997-10-07Fredrik Hübinette (Hubbe) #include "operators.h" #include "builtin_functions.h"
05590d1998-04-23Fredrik Hübinette (Hubbe) #include "module_support.h" #include "fsort.h"
928ad61998-04-27Fredrik Hübinette (Hubbe) #include "threads.h"
3a0fda1998-05-01Henrik Grubbström (Grubba) #include "stuff.h"
a757011998-05-16Fredrik Hübinette (Hubbe) #include "version.h"
52bb181999-10-25Fredrik Hübinette (Hubbe) #include "bignum.h"
3ad9861997-01-26Fredrik Hübinette (Hubbe) 
41fbc12001-08-14Martin Stjernholm RCSID("$Id: encode.c,v 1.86 2001/08/13 23:01:19 mast Exp $");
52bb181999-10-25Fredrik Hübinette (Hubbe)  /* #define ENCODE_DEBUG */
27d61c2001-07-16Martin Stjernholm 
52bb181999-10-25Fredrik Hübinette (Hubbe) #ifdef ENCODE_DEBUG
27d61c2001-07-16Martin Stjernholm /* Pass a nonzero integer as the third arg to encode_value, * encode_value_canonic and decode_value to activate this debug. */ #define EDB(N,X) do if (data->debug>=N) {X;} while (0)
52bb181999-10-25Fredrik Hübinette (Hubbe) #else
27d61c2001-07-16Martin Stjernholm #define EDB(N,X) do {} while (0)
52bb181999-10-25Fredrik Hübinette (Hubbe) #endif
24ddc71998-03-28Henrik Grubbström (Grubba) 
86c5a22000-07-07Henrik Grubbström (Grubba) /* The sp macro conflicts with Solaris 2.5.1's <sys/conf.h>. */ #ifdef sp #undef sp #define STACKPOINTER_WAS_DEFINED #endif /* sp */
3ad9861997-01-26Fredrik Hübinette (Hubbe) #ifdef _AIX #include <net/nh.h> #endif #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif
9d21f91997-01-27Fredrik Hübinette (Hubbe) #include <math.h>
86c5a22000-07-07Henrik Grubbström (Grubba) /* Restore the sp macro */ #ifdef STACKPOINTER_WAS_DEFINED #define sp Pike_sp #undef STACK_POINTER_WAS_DEFINED #endif /* STACKPOINTER_WAS_DEFINED */
892e7f1997-04-06Fredrik Hübinette (Hubbe) #ifdef HAVE_FREXP #define FREXP frexp #else double FREXP(double x, int *exp) { double ret;
f00c362000-08-10Henrik Grubbström (Grubba)  *exp = DO_NOT_WARN((int)ceil(log(fabs(x))/log(2.0))); ret = (x*pow(2.0,(double)-*exp));
e3c7c41997-04-08David KÃ¥gedal  return ret;
892e7f1997-04-06Fredrik Hübinette (Hubbe) } #endif #if HAVE_LDEXP #define LDEXP ldexp #else double LDEXP(double x, int exp) { return x * pow(2.0,(double)exp); } #endif
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
05590d1998-04-23Fredrik Hübinette (Hubbe) #define encode_value2 encode_value2_ #define decode_value2 decode_value2_ #endif
4ba6be1999-12-11Henrik Grubbström (Grubba) /* Tags used by encode value. * Currently they only differ from the PIKE_T variants by * TAG_FLOAT == PIKE_T_TYPE == 7 * and * TAG_TYPE == PIKE_T_FLOAT == 9 * These are NOT to be renumbered unless the file-format version is changed! */
be273a2000-09-11Henrik Grubbström (Grubba) /* Current encoding: ¶ik0 * * +---+-+-+-------+ * |s z|s|n|t y p e| * +---+-+-+-------+ * sz size/small int * s small int indicator * n negative (or rather inverted) * type TAG_type */
4ba6be1999-12-11Henrik Grubbström (Grubba) #define TAG_ARRAY 0 #define TAG_MAPPING 1 #define TAG_MULTISET 2 #define TAG_OBJECT 3 #define TAG_FUNCTION 4 #define TAG_PROGRAM 5 #define TAG_STRING 6 #define TAG_FLOAT 7 #define TAG_INT 8 #define TAG_TYPE 9 /* Not supported yet */ #define TAG_AGAIN 15 #define TAG_MASK 15 #define TAG_NEG 16 #define TAG_SMALL 32 #define SIZE_SHIFT 6 #define MAX_SMALL (1<<(8-SIZE_SHIFT)) #define COUNTER_START -MAX_SMALL
3ad9861997-01-26Fredrik Hübinette (Hubbe) struct encode_data {
657a002000-03-26Martin Stjernholm  int canonic;
05590d1998-04-23Fredrik Hübinette (Hubbe)  struct object *codec;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  struct svalue counter; struct mapping *encoded; dynamic_buffer buf;
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG int debug, depth; #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe) };
05590d1998-04-23Fredrik Hübinette (Hubbe) static void encode_value2(struct svalue *val, struct encode_data *data);
3ad9861997-01-26Fredrik Hübinette (Hubbe) #define addstr(s, l) low_my_binary_strcat((s), (l), &(data->buf))
be273a2000-09-11Henrik Grubbström (Grubba) #define addchar(t) low_my_putchar((char)(t), &(data->buf))
11b69f1999-09-17Fredrik Hübinette (Hubbe)  /* Code a pike string */
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  #if BYTEORDER == 4321 #define ENCODE_DATA(S) \ addstr( (S)->str, (S)->len << (S)->size_shift ); #else #define ENCODE_DATA(S) \ switch((S)->size_shift) \ { \ case 1: \ for(q=0;q<(S)->len;q++) { \ INT16 s=htons( STR1(S)[q] ); \ addstr( (char *)&s, sizeof(s)); \ } \ break; \ case 2: \ for(q=0;q<(S)->len;q++) { \ INT32 s=htonl( STR2(S)[q] ); \ addstr( (char *)&s, sizeof(s)); \ } \ break; \ } #endif #define adddata(S) do { \ if((S)->size_shift) \ { \ int q; \
4ba6be1999-12-11Henrik Grubbström (Grubba)  code_entry(TAG_STRING,-1, data); \
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  code_entry((S)->size_shift, (S)->len, data); \ ENCODE_DATA(S); \ }else{ \
4ba6be1999-12-11Henrik Grubbström (Grubba)  code_entry(TAG_STRING, (S)->len, data); \
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  addstr((char *)((S)->str),(S)->len); \ } \
05590d1998-04-23Fredrik Hübinette (Hubbe) }while(0)
11b69f1999-09-17Fredrik Hübinette (Hubbe) /* Like adddata, but allows null pointers */ #define adddata3(S) do { \ if(S) { \
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  adddata(S); \
11b69f1999-09-17Fredrik Hübinette (Hubbe)  } else { \
4ba6be1999-12-11Henrik Grubbström (Grubba)  code_entry(TAG_INT, 0, data); \
11b69f1999-09-17Fredrik Hübinette (Hubbe)  } \ }while(0)
05590d1998-04-23Fredrik Hübinette (Hubbe) #define adddata2(s,l) addstr((char *)(s),(l) * sizeof(s[0]));
3ad9861997-01-26Fredrik Hübinette (Hubbe) 
4ba6be1999-12-11Henrik Grubbström (Grubba) /* NOTE: Fix when type encodings change. */ static int type_to_tag(int type) { if (type == T_FLOAT) return TAG_FLOAT; if (type == T_TYPE) return TAG_TYPE; return type; } static int (*tag_to_type)(int) = type_to_tag;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  /* Let's cram those bits... */
be273a2000-09-11Henrik Grubbström (Grubba) static void code_entry(int tag, INT64 num, struct encode_data *data)
3ad9861997-01-26Fredrik Hübinette (Hubbe) { int t;
27d61c2001-07-16Martin Stjernholm  EDB(5, fprintf(stderr,"%*sencode: code_entry(tag=%d (%s), num=%ld)\n", data->depth, "", tag,
4ba6be1999-12-11Henrik Grubbström (Grubba)  get_name_of_type(tag_to_type(tag)),
c7241b2000-08-10Henrik Grubbström (Grubba)  (long)num) );
3ad9861997-01-26Fredrik Hübinette (Hubbe)  if(num<0) {
4ba6be1999-12-11Henrik Grubbström (Grubba)  tag |= TAG_NEG; num = ~num;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  } if(num < MAX_SMALL) {
4ba6be1999-12-11Henrik Grubbström (Grubba)  tag |= TAG_SMALL | (num << SIZE_SHIFT);
be273a2000-09-11Henrik Grubbström (Grubba)  addchar((char)tag);
3ad9861997-01-26Fredrik Hübinette (Hubbe)  return; }else{
4ba6be1999-12-11Henrik Grubbström (Grubba)  num -= MAX_SMALL;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  }
be273a2000-09-11Henrik Grubbström (Grubba)  for(t = 0; (size_t)t < #if 0 (sizeof(INT64)-1); #else /* !0 */ (size_t)3; #endif /* 0 */ t++)
3ad9861997-01-26Fredrik Hübinette (Hubbe)  {
be273a2000-09-11Henrik Grubbström (Grubba)  if(num >= (((INT64)256) << (t<<3))) num -= (((INT64)256) << (t<<3));
3ad9861997-01-26Fredrik Hübinette (Hubbe)  else break; }
4ba6be1999-12-11Henrik Grubbström (Grubba)  tag |= t << SIZE_SHIFT;
be273a2000-09-11Henrik Grubbström (Grubba)  addchar((char)tag);
3ad9861997-01-26Fredrik Hübinette (Hubbe)  switch(t) {
be273a2000-09-11Henrik Grubbström (Grubba) #if 0 case 7: addchar(DO_NOT_WARN((char)((num >> 56)&0xff))); case 6: addchar(DO_NOT_WARN((char)((num >> 48)&0xff))); case 5: addchar(DO_NOT_WARN((char)((num >> 40)&0xff))); case 4: addchar(DO_NOT_WARN((char)((num >> 32)&0xff))); #endif /* 0 */ case 3: addchar(DO_NOT_WARN((char)((num >> 24)&0xff))); case 2: addchar(DO_NOT_WARN((char)((num >> 16)&0xff))); case 1: addchar(DO_NOT_WARN((char)((num >> 8)&0xff))); case 0: addchar(DO_NOT_WARN((char)(num&0xff)));
3ad9861997-01-26Fredrik Hübinette (Hubbe)  } }
c7241b2000-08-10Henrik Grubbström (Grubba) static void code_number(ptrdiff_t num, struct encode_data *data)
05590d1998-04-23Fredrik Hübinette (Hubbe) {
f00c362000-08-10Henrik Grubbström (Grubba)  code_entry(DO_NOT_WARN(num & 15), num >> 4, data);
05590d1998-04-23Fredrik Hübinette (Hubbe) }
928ad61998-04-27Fredrik Hübinette (Hubbe) #ifdef _REENTRANT static void do_enable_threads(void) {
f8d8cf1999-07-18Fredrik Hübinette (Hubbe)  exit_threads_disable(NULL);
928ad61998-04-27Fredrik Hübinette (Hubbe) } #endif
f00c362000-08-10Henrik Grubbström (Grubba) static ptrdiff_t encode_type(char *t, struct encode_data *data)
05590d1998-04-23Fredrik Hübinette (Hubbe) { char *q=t; one_more_type: addchar(EXTRACT_UCHAR(t)); switch(EXTRACT_UCHAR(t++)) { default:
a4a1722000-12-05Per Hedbor  fatal("error in type string.\n");
05590d1998-04-23Fredrik Hübinette (Hubbe)  /*NOTREACHED*/
583ade2000-02-16Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  break;
583ade2000-02-16Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_ASSIGN: addchar(EXTRACT_UCHAR(t++)); goto one_more_type;
583ade2000-02-16Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_FUNCTION: while(EXTRACT_UCHAR(t)!=T_MANY) t+=encode_type(t, data); addchar(EXTRACT_UCHAR(t++));
583ade2000-02-16Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_MAPPING: case T_OR: case T_AND: t+=encode_type(t, data);
583ade2000-02-16Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_ARRAY: case T_MULTISET: case T_NOT: goto one_more_type;
583ade2000-02-16Per Hedbor 
8108741999-03-07Henrik Grubbström (Grubba)  case T_INT: { int i;
2377dc1999-03-07Henrik Grubbström (Grubba)  /* FIXME: I assume the type is saved in network byte order. Is it? * /grubba 1999-03-07
f3eff92000-04-06Fredrik Hübinette (Hubbe)  * Yes - Hubbe
2377dc1999-03-07Henrik Grubbström (Grubba)  */
6f772e1999-03-07Henrik Grubbström (Grubba)  for(i = 0; i < (int)(2*sizeof(INT32)); i++) {
8108741999-03-07Henrik Grubbström (Grubba)  addchar(EXTRACT_UCHAR(t++)); } } break;
05590d1998-04-23Fredrik Hübinette (Hubbe)  case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case T_FLOAT: case T_STRING: case T_PROGRAM:
7c29372001-04-19Henrik Grubbström (Grubba)  case T_TYPE:
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_MIXED:
ae44ba1999-11-23Henrik Grubbström (Grubba)  case T_ZERO:
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_VOID:
04966d2000-10-03Fredrik Hübinette (Hubbe)  case PIKE_T_UNKNOWN:
05590d1998-04-23Fredrik Hübinette (Hubbe)  break;
583ade2000-02-16Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_OBJECT: { INT32 x; addchar(EXTRACT_UCHAR(t++)); x=EXTRACT_INT(t); t+=sizeof(INT32); if(x) { struct program *p=id_to_program(x); if(p) { ref_push_program(p); }else{ push_int(0); } }else{ push_int(0); }
fc26f62000-07-06Fredrik Hübinette (Hubbe)  encode_value2(Pike_sp-1, data);
05590d1998-04-23Fredrik Hübinette (Hubbe)  pop_stack(); break; } } return t-q; }
50817d1997-10-07Fredrik Hübinette (Hubbe) 
27d61c2001-07-16Martin Stjernholm static void zap_unfinished_program(struct program *p) { int e; debug_malloc_touch(p); for(e=0;e<p->num_constants;e++) { free_svalue(& p->constants[e].sval); p->constants[e].sval.type=T_INT; DO_IF_DMALLOC(p->constants[e].sval.u.refs=(void *)-1); } for(e=0;e<p->num_inherits;e++) { if(p->inherits[e].parent) { free_object(p->inherits[e].parent); p->inherits[e].parent=0; } if(e) { if(p->inherits[e].prog) { free_program(p->inherits[e].prog); p->inherits[e].prog=0; } } } }
3ad9861997-01-26Fredrik Hübinette (Hubbe) static void encode_value2(struct svalue *val, struct encode_data *data)
50817d1997-10-07Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
50817d1997-10-07Fredrik Hübinette (Hubbe) #undef encode_value2
fc26f62000-07-06Fredrik Hübinette (Hubbe) #define encode_value2(X,Y) do { struct svalue *_=Pike_sp; encode_value2_(X,Y); if(Pike_sp!=_) fatal("encode_value2 failed!\n"); } while(0)
50817d1997-10-07Fredrik Hübinette (Hubbe) #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe) {
50817d1997-10-07Fredrik Hübinette (Hubbe)  static struct svalue dested = { T_INT, NUMBER_DESTRUCTED };
3ad9861997-01-26Fredrik Hübinette (Hubbe)  INT32 i; struct svalue *tmp;
583ade2000-02-16Per Hedbor 
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG data->depth += 2; #endif
be273a2000-09-11Henrik Grubbström (Grubba)  if((val->type == T_OBJECT || (val->type==T_FUNCTION && val->subtype!=FUNCTION_BUILTIN)) && !val->u.object->prog) val = &dested;
583ade2000-02-16Per Hedbor 
9c6f7d1997-04-15Fredrik Hübinette (Hubbe)  if((tmp=low_mapping_lookup(data->encoded, val)))
3ad9861997-01-26Fredrik Hübinette (Hubbe)  {
27d61c2001-07-16Martin Stjernholm  EDB(1,fprintf(stderr, "%*sEncoding TAG_AGAIN from <%d>\n", data->depth, "", tmp->u.integer));
4ba6be1999-12-11Henrik Grubbström (Grubba)  code_entry(TAG_AGAIN, tmp->u.integer, data);
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG data->depth -= 2; #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe)  return;
27d61c2001-07-16Martin Stjernholm  }else if (val->type != T_TYPE) { EDB(1,fprintf(stderr, "%*sEncoding to <%d>: ", data->depth, "", data->counter.u.integer); if(data->debug == 1) { fprintf(stderr,"TAG%d",val->type); }else{ print_svalue(stderr, val); } fputc('\n', stderr););
3ad9861997-01-26Fredrik Hübinette (Hubbe)  mapping_insert(data->encoded, val, &data->counter); data->counter.u.integer++; }
583ade2000-02-16Per Hedbor 
3ad9861997-01-26Fredrik Hübinette (Hubbe)  switch(val->type) {
50817d1997-10-07Fredrik Hübinette (Hubbe)  case T_INT:
52bb181999-10-25Fredrik Hübinette (Hubbe)  /* FIXME: * if INT_TYPE is larger than 32 bits (not currently happening) * then this must be fixed to encode numbers over 32 bits as * Gmp.mpz objects */
4ba6be1999-12-11Henrik Grubbström (Grubba)  code_entry(TAG_INT, val->u.integer,data);
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  case T_STRING:
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  adddata(val->u.string);
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
0dd0fa1999-12-11Henrik Grubbström (Grubba) 
69b77c1999-12-11Henrik Grubbström (Grubba)  case T_TYPE:
7c29372001-04-19Henrik Grubbström (Grubba)  /* NOTE: Types are added to the encoded mapping AFTER they have * been encoded, to simplify decoding. */
657a002000-03-26Martin Stjernholm  if (data->canonic)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Canonical encoding of the type type not supported.\n");
7c29372001-04-19Henrik Grubbström (Grubba)  code_entry(TAG_TYPE, 0, data); /* Type encoding #0 */ encode_type(val->u.string->str, data);
27d61c2001-07-16Martin Stjernholm  EDB(2,fprintf(stderr, "%*sEncoded type to <%d>: ", data->depth, "", data->counter.u.integer); print_svalue(stderr, val); fputc('\n', stderr););
7c29372001-04-19Henrik Grubbström (Grubba)  mapping_insert(data->encoded, val, &data->counter); data->counter.u.integer++;
69b77c1999-12-11Henrik Grubbström (Grubba)  break;
50817d1997-10-07Fredrik Hübinette (Hubbe)  case T_FLOAT:
3ad9861997-01-26Fredrik Hübinette (Hubbe)  {
50817d1997-10-07Fredrik Hübinette (Hubbe)  if(val->u.float_number==0.0)
3ad9861997-01-26Fredrik Hübinette (Hubbe)  {
4ba6be1999-12-11Henrik Grubbström (Grubba)  code_entry(TAG_FLOAT,0,data); code_entry(TAG_FLOAT,0,data);
50817d1997-10-07Fredrik Hübinette (Hubbe)  }else{
be273a2000-09-11Henrik Grubbström (Grubba)  INT64 x;
50817d1997-10-07Fredrik Hübinette (Hubbe)  int y; double tmp;
583ade2000-02-16Per Hedbor 
f00c362000-08-10Henrik Grubbström (Grubba)  tmp = FREXP((double)val->u.float_number, &y);
be273a2000-09-11Henrik Grubbström (Grubba)  x = DO_NOT_WARN((INT64)((((INT64)1)<<(sizeof(INT64)*8 - 2))*tmp)); y -= sizeof(INT64)*8 - 2;
27d61c2001-07-16Martin Stjernholm  EDB(2,fprintf(stderr,
be273a2000-09-11Henrik Grubbström (Grubba)  "Encoding float... tmp: %10g, x: 0x%016llx, y: %d\n", tmp, x, y)); #if 0 if (x && !(x & 0xffffffffUL)) { #endif /* 0 */ x >>= 32; y += 32;
27d61c2001-07-16Martin Stjernholm  EDB(2,fprintf(stderr,
be273a2000-09-11Henrik Grubbström (Grubba)  "Reducing float... x: 0x%08llx, y: %d\n", x, y)); #if 0 } #endif /* 0 */
d34da71997-10-19Fredrik Hübinette (Hubbe) #if 0
50817d1997-10-07Fredrik Hübinette (Hubbe)  while(x && y && !(x&1)) { x>>=1; y++; }
d34da71997-10-19Fredrik Hübinette (Hubbe) #endif
4ba6be1999-12-11Henrik Grubbström (Grubba)  code_entry(TAG_FLOAT,x,data); code_entry(TAG_FLOAT,y,data);
3ad9861997-01-26Fredrik Hübinette (Hubbe)  }
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  }
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  case T_ARRAY:
4ba6be1999-12-11Henrik Grubbström (Grubba)  code_entry(TAG_ARRAY, val->u.array->size, data);
50817d1997-10-07Fredrik Hübinette (Hubbe)  for(i=0; i<val->u.array->size; i++) encode_value2(ITEM(val->u.array)+i, data); break;
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  case T_MAPPING: check_stack(2); ref_push_mapping(val->u.mapping); f_indices(1);
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  ref_push_mapping(val->u.mapping); f_values(1);
583ade2000-02-16Per Hedbor 
657a002000-03-26Martin Stjernholm  if (data->canonic) { INT32 *order; if (val->u.mapping->data->ind_types & ~(BIT_BASIC & ~BIT_TYPE)) { mapping_fix_type_field(val->u.mapping); if (val->u.mapping->data->ind_types & ~(BIT_BASIC & ~BIT_TYPE)) /* This doesn't let bignums through. That's necessary as * long as they aren't handled deterministically by the * sort function. */
49398c2000-11-08Fredrik Hübinette (Hubbe)  /* They should be hanled deterministically now - Hubbe */
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Canonical encoding requires basic types in indices.\n");
657a002000-03-26Martin Stjernholm  }
fc26f62000-07-06Fredrik Hübinette (Hubbe)  order = get_switch_order(Pike_sp[-2].u.array); order_array(Pike_sp[-2].u.array, order); order_array(Pike_sp[-1].u.array, order);
657a002000-03-26Martin Stjernholm  free((char *) order); }
fc26f62000-07-06Fredrik Hübinette (Hubbe)  code_entry(TAG_MAPPING, Pike_sp[-2].u.array->size,data); for(i=0; i<Pike_sp[-2].u.array->size; i++)
50817d1997-10-07Fredrik Hübinette (Hubbe)  {
fc26f62000-07-06Fredrik Hübinette (Hubbe)  encode_value2(ITEM(Pike_sp[-2].u.array)+i, data); /* indices */ encode_value2(ITEM(Pike_sp[-1].u.array)+i, data); /* values */
50817d1997-10-07Fredrik Hübinette (Hubbe)  } pop_n_elems(2); break;
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  case T_MULTISET:
4ba6be1999-12-11Henrik Grubbström (Grubba)  code_entry(TAG_MULTISET, val->u.multiset->ind->size,data);
657a002000-03-26Martin Stjernholm  if (data->canonic) { INT32 *order; if (val->u.multiset->ind->type_field & ~(BIT_BASIC & ~BIT_TYPE)) { array_fix_type_field(val->u.multiset->ind); if (val->u.multiset->ind->type_field & ~(BIT_BASIC & ~BIT_TYPE)) /* This doesn't let bignums through. That's necessary as * long as they aren't handled deterministically by the * sort function. */
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Canonical encoding requires basic types in indices.\n");
657a002000-03-26Martin Stjernholm  } check_stack(1); ref_push_array(val->u.multiset->ind);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  order = get_switch_order(Pike_sp[-1].u.array); order_array(Pike_sp[-1].u.array, order);
657a002000-03-26Martin Stjernholm  free((char *) order);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  for (i = 0; i < Pike_sp[-1].u.array->size; i++) encode_value2(ITEM(Pike_sp[-1].u.array)+i, data);
657a002000-03-26Martin Stjernholm  pop_stack(); } else for(i=0; i<val->u.multiset->ind->size; i++) encode_value2(ITEM(val->u.multiset->ind)+i, data);
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  case T_OBJECT: check_stack(1);
52bb181999-10-25Fredrik Hübinette (Hubbe)  #ifdef AUTO_BIGNUM /* This could be implemented a lot more generic, * but that will have to wait until next time. /Hubbe */ if(is_bignum_object(val->u.object)) {
4ba6be1999-12-11Henrik Grubbström (Grubba)  code_entry(TAG_OBJECT, 2, data);
52bb181999-10-25Fredrik Hübinette (Hubbe)  /* 256 would be better, but then negative numbers * doesn't work... /Hubbe */ push_int(36); apply(val->u.object,"digits",1);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].type != T_STRING)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Gmp.mpz->digits did not return a string!\n");
fc26f62000-07-06Fredrik Hübinette (Hubbe)  encode_value2(Pike_sp-1, data);
52bb181999-10-25Fredrik Hübinette (Hubbe)  pop_stack(); break; } #endif
583ade2000-02-16Per Hedbor 
657a002000-03-26Martin Stjernholm  if (data->canonic)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Canonical encoding of objects not supported.\n");
50817d1997-10-07Fredrik Hübinette (Hubbe)  push_svalue(val);
05590d1998-04-23Fredrik Hübinette (Hubbe)  apply(data->codec, "nameof", 1);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  switch(Pike_sp[-1].type)
50817d1997-10-07Fredrik Hübinette (Hubbe)  { case T_INT:
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].subtype == NUMBER_UNDEFINED)
50817d1997-10-07Fredrik Hübinette (Hubbe)  {
27d61c2001-07-16Martin Stjernholm  int to_change = data->buf.s.len; struct svalue tmp=data->counter; tmp.u.integer--; /* We have to remove ourself from the cache */ map_delete(data->encoded, val);
50817d1997-10-07Fredrik Hübinette (Hubbe)  pop_stack();
05590d1998-04-23Fredrik Hübinette (Hubbe)  push_svalue(val); f_object_program(1);
583ade2000-02-16Per Hedbor 
27d61c2001-07-16Martin Stjernholm  /* Code the program */ code_entry(TAG_OBJECT, 3,data);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  encode_value2(Pike_sp-1, data);
05590d1998-04-23Fredrik Hübinette (Hubbe)  pop_stack();
27d61c2001-07-16Martin Stjernholm 
50817d1997-10-07Fredrik Hübinette (Hubbe)  push_svalue(val);
27d61c2001-07-16Martin Stjernholm  /* If we do not exist in cache, use backwards- * compatible method, otherwise use newfangled * style=3. -Hubbe */ if(!low_mapping_lookup(data->encoded, val)) { EDB(1,fprintf(stderr, "%*sZapping 3 -> 1 in TAG_OBJECT\n", data->depth, "")); /* This causes the code_entry above to * become: code_entry(TAG_OBJECT, 1, data); * -Hubbe */ data->buf.s.str[to_change] = 99; apply(data->codec,"encode_object",1); /* Put value back in cache for future reference -Hubbe */ mapping_insert(data->encoded, val, &tmp); }
50817d1997-10-07Fredrik Hübinette (Hubbe)  break; } /* FALL THROUGH */
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  default:
27d61c2001-07-16Martin Stjernholm  code_entry(TAG_OBJECT, 0,data);
50817d1997-10-07Fredrik Hübinette (Hubbe)  break; }
fc26f62000-07-06Fredrik Hübinette (Hubbe)  encode_value2(Pike_sp-1, data);
50817d1997-10-07Fredrik Hübinette (Hubbe)  pop_stack(); break;
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  case T_FUNCTION:
657a002000-03-26Martin Stjernholm  if (data->canonic)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Canonical encoding of functions not supported.\n");
50817d1997-10-07Fredrik Hübinette (Hubbe)  check_stack(1); push_svalue(val);
05590d1998-04-23Fredrik Hübinette (Hubbe)  apply(data->codec,"nameof", 1);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].type == T_INT && Pike_sp[-1].subtype==NUMBER_UNDEFINED)
50817d1997-10-07Fredrik Hübinette (Hubbe)  { if(val->subtype != FUNCTION_BUILTIN) { int eq;
4ba6be1999-12-11Henrik Grubbström (Grubba)  code_entry(type_to_tag(val->type), 1, data);
50817d1997-10-07Fredrik Hübinette (Hubbe)  push_svalue(val);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  Pike_sp[-1].type=T_OBJECT;
50817d1997-10-07Fredrik Hübinette (Hubbe)  ref_push_string(ID_FROM_INT(val->u.object->prog, val->subtype)->name); f_arrow(2);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  eq=is_eq(Pike_sp-1, val);
50817d1997-10-07Fredrik Hübinette (Hubbe)  pop_stack(); if(eq) { /* We have to remove ourself from the cache for now */ struct svalue tmp=data->counter; tmp.u.integer--; map_delete(data->encoded, val);
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  push_svalue(val);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  Pike_sp[-1].type=T_OBJECT; encode_value2(Pike_sp-1, data);
50817d1997-10-07Fredrik Hübinette (Hubbe)  ref_push_string(ID_FROM_INT(val->u.object->prog, val->subtype)->name);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  encode_value2(Pike_sp-1, data);
50817d1997-10-07Fredrik Hübinette (Hubbe)  pop_n_elems(3);
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  /* Put value back in cache */ mapping_insert(data->encoded, val, &tmp);
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG data->depth -= 2; #endif
50817d1997-10-07Fredrik Hübinette (Hubbe)  return; } }
27d61c2001-07-16Martin Stjernholm  Pike_error("Encoding of efuns is not supported yet.\n");
50817d1997-10-07Fredrik Hübinette (Hubbe)  }
3ad9861997-01-26Fredrik Hübinette (Hubbe) 
4ba6be1999-12-11Henrik Grubbström (Grubba)  code_entry(type_to_tag(val->type), 0,data);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  encode_value2(Pike_sp-1, data);
50817d1997-10-07Fredrik Hübinette (Hubbe)  pop_stack(); break;
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  case T_PROGRAM:
05590d1998-04-23Fredrik Hübinette (Hubbe)  { int d;
657a002000-03-26Martin Stjernholm  if (data->canonic)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Canonical encoding of programs not supported.\n");
50817d1997-10-07Fredrik Hübinette (Hubbe)  check_stack(1); push_svalue(val);
05590d1998-04-23Fredrik Hübinette (Hubbe)  apply(data->codec,"nameof", 1);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].type == val->type)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Error in master()->nameof(), same type returned.\n");
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].type == T_INT && Pike_sp[-1].subtype == NUMBER_UNDEFINED)
05590d1998-04-23Fredrik Hübinette (Hubbe)  { INT32 e; struct program *p=val->u.program;
a5bd2b2000-06-10Martin Stjernholm  if(p->init || p->exit || p->gc_recurse_func || p->gc_check_func ||
05590d1998-04-23Fredrik Hübinette (Hubbe)  (p->flags & PROGRAM_HAS_C_METHODS))
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot encode C programs.\n");
4ba6be1999-12-11Henrik Grubbström (Grubba)  code_entry(type_to_tag(val->type), 1,data);
a757011998-05-16Fredrik Hübinette (Hubbe)  f_version(0);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  encode_value2(Pike_sp-1,data);
a757011998-05-16Fredrik Hübinette (Hubbe)  pop_stack();
05590d1998-04-23Fredrik Hübinette (Hubbe)  code_number(p->flags,data); code_number(p->storage_needed,data);
8f29a31999-09-15Fredrik Hübinette (Hubbe)  code_number(p->alignment_needed,data);
05590d1998-04-23Fredrik Hübinette (Hubbe)  code_number(p->timestamp.tv_sec,data); code_number(p->timestamp.tv_usec,data); #define FOO(X,Y,Z) \
27d61c2001-07-16Martin Stjernholm  code_number( p->PIKE_CONCAT(num_,Z), data);
05590d1998-04-23Fredrik Hübinette (Hubbe) #include "program_areas.h" adddata2(p->program, p->num_program); adddata2(p->linenumbers, p->num_linenumbers); for(d=0;d<p->num_identifier_index;d++) code_number(p->identifier_index[d],data); for(d=0;d<p->num_variable_index;d++) code_number(p->variable_index[d],data); for(d=0;d<p->num_identifier_references;d++) { code_number(p->identifier_references[d].inherit_offset,data); code_number(p->identifier_references[d].identifier_offset,data); code_number(p->identifier_references[d].id_flags,data);
27d61c2001-07-16Martin Stjernholm  EDB(3,fprintf(stderr,"IDREF%x > %d: { %d, %d, %d }\n", p->id,d, p->identifier_references[d].inherit_offset, p->identifier_references[d].identifier_offset, p->identifier_references[d].id_flags););
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
583ade2000-02-16Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  for(d=0;d<p->num_strings;d++) adddata(p->strings[d]);
2ad3c01999-09-16Fredrik Hübinette (Hubbe)  for(d=0;d<p->num_inherits;d++)
05590d1998-04-23Fredrik Hübinette (Hubbe)  { code_number(p->inherits[d].inherit_level,data); code_number(p->inherits[d].identifier_level,data); code_number(p->inherits[d].parent_offset,data);
0d2c872000-09-30Fredrik Hübinette (Hubbe)  code_number(p->inherits[d].parent_identifier,data);
05590d1998-04-23Fredrik Hübinette (Hubbe)  code_number(p->inherits[d].storage_offset,data); if(p->inherits[d].parent) { ref_push_object(p->inherits[d].parent);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  Pike_sp[-1].subtype=p->inherits[d].parent_identifier; Pike_sp[-1].type=T_FUNCTION;
27d61c2001-07-16Martin Stjernholm  EDB(3,fprintf(stderr,"INHERIT%x coded as func { %p, %d }\n", p->id, p->inherits[d].parent, p->inherits[d].parent_identifier););
05590d1998-04-23Fredrik Hübinette (Hubbe)  }else if(p->inherits[d].prog){ ref_push_program(p->inherits[d].prog); }else{
27d61c2001-07-16Martin Stjernholm  Pike_error("Failed to encode inherit #%d\n", d);
05590d1998-04-23Fredrik Hübinette (Hubbe)  push_int(0); }
fc26f62000-07-06Fredrik Hübinette (Hubbe)  encode_value2(Pike_sp-1,data);
05590d1998-04-23Fredrik Hübinette (Hubbe)  pop_stack();
11b69f1999-09-17Fredrik Hübinette (Hubbe)  adddata3(p->inherits[d].name);
27d61c2001-07-16Martin Stjernholm  EDB(3,fprintf(stderr,"INHERIT%x > %d: %d id=%d\n", p->id,d, p->inherits[d].prog->num_identifiers, p->inherits[d].prog->id););
05590d1998-04-23Fredrik Hübinette (Hubbe)  } for(d=0;d<p->num_identifiers;d++) { adddata(p->identifiers[d].name); encode_type(p->identifiers[d].type->str, data); code_number(p->identifiers[d].identifier_flags,data); code_number(p->identifiers[d].run_time_type,data);
5e84532000-08-30Fredrik Hübinette (Hubbe)  code_number(p->identifiers[d].opt_flags,data);
27d61c2001-07-16Martin Stjernholm  if (!(p->identifiers[d].identifier_flags & IDENTIFIER_C_FUNCTION)) { code_number(p->identifiers[d].func.offset,data); } else { Pike_error("Cannot encode functions implemented in C " "(identifier='%s').\n", p->identifiers[d].name->str); }
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
27d61c2001-07-16Martin Stjernholm  for(d=0;d<NUM_LFUNS;d++) code_number(p->lfuns[d], data);
05590d1998-04-23Fredrik Hübinette (Hubbe)  for(d=0;d<p->num_constants;d++)
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  { encode_value2(& p->constants[d].sval, data); adddata3(p->constants[d].name); }
05590d1998-04-23Fredrik Hübinette (Hubbe)  }else{
4ba6be1999-12-11Henrik Grubbström (Grubba)  code_entry(type_to_tag(val->type), 0,data);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  encode_value2(Pike_sp-1, data);
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
50817d1997-10-07Fredrik Hübinette (Hubbe)  pop_stack(); break;
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
3ad9861997-01-26Fredrik Hübinette (Hubbe)  }
27d61c2001-07-16Martin Stjernholm  #ifdef ENCODE_DEBUG data->depth -= 2; #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe) } static void free_encode_data(struct encode_data *data) { toss_buffer(& data->buf); free_mapping(data->encoded); } void f_encode_value(INT32 args) { ONERROR tmp; struct encode_data d, *data; data=&d;
583ade2000-02-16Per Hedbor 
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG check_all_args("encode_value", args, BIT_MIXED, BIT_VOID | BIT_OBJECT, BIT_VOID | BIT_INT, 0); #else
05590d1998-04-23Fredrik Hübinette (Hubbe)  check_all_args("encode_value", args, BIT_MIXED, BIT_VOID | BIT_OBJECT, 0);
27d61c2001-07-16Martin Stjernholm #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe)  initialize_buf(&data->buf);
657a002000-03-26Martin Stjernholm  data->canonic = 0; data->encoded=allocate_mapping(128); data->counter.type=T_INT; data->counter.u.integer=COUNTER_START; if(args > 1) {
fc26f62000-07-06Fredrik Hübinette (Hubbe)  data->codec=Pike_sp[1-args].u.object;
657a002000-03-26Martin Stjernholm  }else{ data->codec=get_master(); }
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG data->debug = args > 2 ? Pike_sp[2-args].u.integer : 0; data->depth = -2; #endif
657a002000-03-26Martin Stjernholm  SET_ONERROR(tmp, free_encode_data, data); addstr("\266ke0", 4);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  encode_value2(Pike_sp-args, data);
657a002000-03-26Martin Stjernholm  UNSET_ONERROR(tmp); free_mapping(data->encoded); pop_n_elems(args); push_string(low_free_buf(&data->buf)); } void f_encode_value_canonic(INT32 args) { ONERROR tmp; struct encode_data d, *data; data=&d;
27d61c2001-07-16Martin Stjernholm  #ifdef ENCODE_DEBUG check_all_args("encode_value_canonic", args, BIT_MIXED, BIT_VOID | BIT_OBJECT, BIT_VOID | BIT_INT, 0); #else
657a002000-03-26Martin Stjernholm  check_all_args("encode_value_canonic", args, BIT_MIXED, BIT_VOID | BIT_OBJECT, 0);
27d61c2001-07-16Martin Stjernholm #endif
657a002000-03-26Martin Stjernholm  initialize_buf(&data->buf); data->canonic = 1;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  data->encoded=allocate_mapping(128); data->counter.type=T_INT; data->counter.u.integer=COUNTER_START;
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(args > 1) {
fc26f62000-07-06Fredrik Hübinette (Hubbe)  data->codec=Pike_sp[1-args].u.object;
05590d1998-04-23Fredrik Hübinette (Hubbe)  }else{ data->codec=get_master(); }
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG data->debug = args > 2 ? Pike_sp[2-args].u.integer : 0; data->depth = -2; #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe)  SET_ONERROR(tmp, free_encode_data, data); addstr("\266ke0", 4);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  encode_value2(Pike_sp-args, data);
3ad9861997-01-26Fredrik Hübinette (Hubbe)  UNSET_ONERROR(tmp); free_mapping(data->encoded);
05590d1998-04-23Fredrik Hübinette (Hubbe) 
3ad9861997-01-26Fredrik Hübinette (Hubbe)  pop_n_elems(args); push_string(low_free_buf(&data->buf)); }
27d61c2001-07-16Martin Stjernholm  struct unfinished_prog_link { struct unfinished_prog_link *next; struct program *prog; }; struct unfinished_obj_link { struct unfinished_obj_link *next; struct object *o; };
3ad9861997-01-26Fredrik Hübinette (Hubbe) struct decode_data { unsigned char *data;
f00c362000-08-10Henrik Grubbström (Grubba)  ptrdiff_t len; ptrdiff_t ptr;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  struct mapping *decoded;
27d61c2001-07-16Martin Stjernholm  struct unfinished_prog_link *unfinished_programs; struct unfinished_obj_link *unfinished_objects;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  struct svalue counter;
05590d1998-04-23Fredrik Hübinette (Hubbe)  struct object *codec; int pickyness;
27d61c2001-07-16Martin Stjernholm  struct pike_string *raw; struct decode_data *next;
41fbc12001-08-14Martin Stjernholm #ifdef PIKE_THREADS struct object *thread_id; #endif
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG int debug, depth; #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe) };
05590d1998-04-23Fredrik Hübinette (Hubbe) static void decode_value2(struct decode_data *data);
9cba792001-01-25Fredrik Hübinette (Hubbe) static void fallback_codec(void) { size_t x; push_constant_text("."); f_divide(2); f_reverse(1); Pike_sp--; x=Pike_sp->u.array->size; push_array_items(Pike_sp->u.array); ref_push_mapping(get_builtin_constants()); while(x--) { stack_swap(); f_arrow(2); } }
3ad9861997-01-26Fredrik Hübinette (Hubbe) static int my_extract_char(struct decode_data *data) {
9d21f91997-01-27Fredrik Hübinette (Hubbe)  if(data->ptr >= data->len)
a4a1722000-12-05Per Hedbor  Pike_error("Format error, not enough data in string.\n");
3ad9861997-01-26Fredrik Hübinette (Hubbe)  return data->data [ data->ptr++ ]; } #define GETC() my_extract_char(data)
52bb181999-10-25Fredrik Hübinette (Hubbe) #define DECODE(Z) do { \
27d61c2001-07-16Martin Stjernholm  EDB(5, \ fprintf(stderr,"%*sdecode(%s) at %d: ", \ data->depth,"",(Z),__LINE__)); \
52bb181999-10-25Fredrik Hübinette (Hubbe)  what=GETC(); \ e=what>>SIZE_SHIFT; \
be273a2000-09-11Henrik Grubbström (Grubba)  numh=0; \
4ba6be1999-12-11Henrik Grubbström (Grubba)  if(what & TAG_SMALL) { \
52bb181999-10-25Fredrik Hübinette (Hubbe)  num=e; \ } else { \
be273a2000-09-11Henrik Grubbström (Grubba)  INT32 numl; \
52bb181999-10-25Fredrik Hübinette (Hubbe)  num=0; \
be273a2000-09-11Henrik Grubbström (Grubba)  while(e > 4) { \ numh = (numh<<8) + (GETC()+1); \ e--; \ } \
52bb181999-10-25Fredrik Hübinette (Hubbe)  while(e-->=0) num=(num<<8) + (GETC()+1); \
be273a2000-09-11Henrik Grubbström (Grubba)  numl = num + MAX_SMALL - 1; \ if (numl < num) numh++; \ num = numl; \ } \ if(what & TAG_NEG) { \ num = ~num; \ numh = ~numh; \
52bb181999-10-25Fredrik Hübinette (Hubbe)  } \
27d61c2001-07-16Martin Stjernholm  EDB(5, \
be273a2000-09-11Henrik Grubbström (Grubba)  fprintf(stderr,"type=%d (%s), num=%ld\n", \
4ba6be1999-12-11Henrik Grubbström (Grubba)  (what & TAG_MASK), \ get_name_of_type(tag_to_type(what & TAG_MASK)), \
be273a2000-09-11Henrik Grubbström (Grubba)  (long)num) ); \
583ade2000-02-16Per Hedbor } while (0)
52bb181999-10-25Fredrik Hübinette (Hubbe) 
3ad9861997-01-26Fredrik Hübinette (Hubbe) 
05590d1998-04-23Fredrik Hübinette (Hubbe)  #define decode_entry(X,Y,Z) \ do { \
be273a2000-09-11Henrik Grubbström (Grubba)  INT32 what, e, num, numh; \ DECODE("decode_entry"); \ if((what & TAG_MASK) != (X)) \
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode, wrong bits (%d).\n", what & TAG_MASK); \
05590d1998-04-23Fredrik Hübinette (Hubbe)  (Y)=num; \ } while(0); #define getdata2(S,L) do { \
f00c362000-08-10Henrik Grubbström (Grubba)  if(data->ptr + (ptrdiff_t)(sizeof(S[0])*(L)) > data->len) \
a4a1722000-12-05Per Hedbor  Pike_error("Failed to decode string. (string range error)\n"); \
05590d1998-04-23Fredrik Hübinette (Hubbe)  MEMCPY((S),(data->data + data->ptr), sizeof(S[0])*(L)); \ data->ptr+=sizeof(S[0])*(L); \ }while(0)
b9a7b01999-09-18Fredrik Hübinette (Hubbe) #if BYTEORDER == 4123 #define BITFLIP(S) #else #define BITFLIP(S) \ switch(what) \ { \ case 1: for(e=0;e<num;e++) STR1(S)[e]=ntohs(STR1(S)[e]); break; \ case 2: for(e=0;e<num;e++) STR2(S)[e]=ntohl(STR2(S)[e]); break; \ } #endif #define get_string_data(STR,LEN, data) do { \ if((LEN) == -1) \ { \
be273a2000-09-11Henrik Grubbström (Grubba)  INT32 what, e, num, numh; \
52bb181999-10-25Fredrik Hübinette (Hubbe)  DECODE("get_string_data"); \
be273a2000-09-11Henrik Grubbström (Grubba)  what &= TAG_MASK; \
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  if(data->ptr + num > data->len || num <0) \
a4a1722000-12-05Per Hedbor  Pike_error("Failed to decode string. (string range error)\n"); \
be273a2000-09-11Henrik Grubbström (Grubba)  if(what<0 || what>2) \
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode string. (Illegal size shift)\n"); \
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  STR=begin_wide_shared_string(num, what); \ MEMCPY(STR->str, data->data + data->ptr, num << what); \ data->ptr+=(num << what); \ BITFLIP(STR); \ STR=end_shared_string(STR); \ }else{ \ if(data->ptr + (LEN) > data->len || (LEN) <0) \
a4a1722000-12-05Per Hedbor  Pike_error("Failed to decode string. (string range error)\n"); \
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  STR=make_shared_binary_string((char *)(data->data + data->ptr), (LEN)); \ data->ptr+=(LEN); \ } \ }while(0) #define getdata(X) do { \ long length; \
4ba6be1999-12-11Henrik Grubbström (Grubba)  decode_entry(TAG_STRING, length,data); \
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  get_string_data(X, length, data); \
05590d1998-04-23Fredrik Hübinette (Hubbe)  }while(0)
11b69f1999-09-17Fredrik Hübinette (Hubbe) #define getdata3(X) do { \
be273a2000-09-11Henrik Grubbström (Grubba)  INT32 what, e, num, numh; \
52bb181999-10-25Fredrik Hübinette (Hubbe)  DECODE("getdata3"); \
4ba6be1999-12-11Henrik Grubbström (Grubba)  switch(what & TAG_MASK) \
11b69f1999-09-17Fredrik Hübinette (Hubbe)  { \
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_INT: \
11b69f1999-09-17Fredrik Hübinette (Hubbe)  X=0; \ break; \ \
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_STRING: \
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  get_string_data(X,num,data); \
11b69f1999-09-17Fredrik Hübinette (Hubbe)  break; \ \ default: \
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode string, tag is wrong: %d\n", \
4ba6be1999-12-11Henrik Grubbström (Grubba)  what & TAG_MASK); \
11b69f1999-09-17Fredrik Hübinette (Hubbe)  } \ }while(0)
05590d1998-04-23Fredrik Hübinette (Hubbe) #define decode_number(X,data) do { \
be273a2000-09-11Henrik Grubbström (Grubba)  INT32 what, e, num, numh; \
52bb181999-10-25Fredrik Hübinette (Hubbe)  DECODE("decode_number"); \
4ba6be1999-12-11Henrik Grubbström (Grubba)  X=(what & TAG_MASK) | (num<<4); \
05590d1998-04-23Fredrik Hübinette (Hubbe)  }while(0) \
770c7d1999-11-03Henrik Grubbström (Grubba) static void restore_type_stack(unsigned char *old_stackp) { #if 0 fprintf(stderr, "Restoring type-stack: %p => %p\n",
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->type_stackp, old_stackp);
770c7d1999-11-03Henrik Grubbström (Grubba) #endif /* 0 */ #ifdef PIKE_DEBUG
bad5162000-06-23Fredrik Hübinette (Hubbe)  if (old_stackp > Pike_compiler->type_stackp) {
770c7d1999-11-03Henrik Grubbström (Grubba)  fatal("type stack out of sync!\n"); } #endif /* PIKE_DEBUG */
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->type_stackp = old_stackp;
770c7d1999-11-03Henrik Grubbström (Grubba) } static void restore_type_mark(unsigned char **old_type_mark_stackp) { #if 0 fprintf(stderr, "Restoring type-mark: %p => %p\n",
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->pike_type_mark_stackp, old_type_mark_stackp);
770c7d1999-11-03Henrik Grubbström (Grubba) #endif /* 0 */ #ifdef PIKE_DEBUG
bad5162000-06-23Fredrik Hübinette (Hubbe)  if (old_type_mark_stackp > Pike_compiler->pike_type_mark_stackp) {
fc26f62000-07-06Fredrik Hübinette (Hubbe)  fatal("type Pike_interpreter.mark_stack out of sync!\n");
770c7d1999-11-03Henrik Grubbström (Grubba)  } #endif /* PIKE_DEBUG */
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->pike_type_mark_stackp = old_type_mark_stackp;
770c7d1999-11-03Henrik Grubbström (Grubba) }
05590d1998-04-23Fredrik Hübinette (Hubbe) static void low_decode_type(struct decode_data *data) {
4ba6be1999-12-11Henrik Grubbström (Grubba)  /* FIXME: Probably ought to use the tag encodings too. */
05590d1998-04-23Fredrik Hübinette (Hubbe)  int tmp;
770c7d1999-11-03Henrik Grubbström (Grubba)  ONERROR err1; ONERROR err2;
bad5162000-06-23Fredrik Hübinette (Hubbe)  SET_ONERROR(err1, restore_type_stack, Pike_compiler->type_stackp); SET_ONERROR(err2, restore_type_mark, Pike_compiler->pike_type_mark_stackp);
770c7d1999-11-03Henrik Grubbström (Grubba) 
05590d1998-04-23Fredrik Hübinette (Hubbe) one_more_type:
f777702000-02-09Henrik Grubbström (Grubba)  tmp = GETC(); push_type(tmp);
05590d1998-04-23Fredrik Hübinette (Hubbe)  switch(tmp) { default:
a4a1722000-12-05Per Hedbor  fatal("error in type string.\n");
05590d1998-04-23Fredrik Hübinette (Hubbe)  /*NOTREACHED*/ break;
583ade2000-02-16Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_ASSIGN: push_type(GETC()); goto one_more_type;
583ade2000-02-16Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_FUNCTION: while(GETC()!=T_MANY) { data->ptr--; low_decode_type(data); } push_type(T_MANY);
583ade2000-02-16Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_MAPPING: case T_OR: case T_AND: low_decode_type(data); case T_ARRAY: case T_MULTISET: case T_NOT: goto one_more_type;
2377dc1999-03-07Henrik Grubbström (Grubba)  case T_INT: { int i; /* FIXME: I assume the type is saved in network byte order. Is it? * /grubba 1999-03-07 */
6f772e1999-03-07Henrik Grubbström (Grubba)  for(i = 0; i < (int)(2*sizeof(INT32)); i++) {
2377dc1999-03-07Henrik Grubbström (Grubba)  push_type(GETC()); } } break;
05590d1998-04-23Fredrik Hübinette (Hubbe)  case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case T_FLOAT:
0dd0fa1999-12-11Henrik Grubbström (Grubba)  case T_TYPE:
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_STRING: case T_PROGRAM: case T_MIXED:
ae44ba1999-11-23Henrik Grubbström (Grubba)  case T_ZERO:
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_VOID:
04966d2000-10-03Fredrik Hübinette (Hubbe)  case PIKE_T_UNKNOWN:
05590d1998-04-23Fredrik Hübinette (Hubbe)  break;
583ade2000-02-16Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_OBJECT: { INT32 x;
770c7d1999-11-03Henrik Grubbström (Grubba) 
05590d1998-04-23Fredrik Hübinette (Hubbe)  push_type(GETC()); decode_value2(data); type_stack_mark();
fc26f62000-07-06Fredrik Hübinette (Hubbe)  switch(Pike_sp[-1].type)
05590d1998-04-23Fredrik Hübinette (Hubbe)  { case T_INT: push_type_int(0); break; case T_PROGRAM:
fc26f62000-07-06Fredrik Hübinette (Hubbe)  push_type_int(Pike_sp[-1].u.program->id);
05590d1998-04-23Fredrik Hübinette (Hubbe)  break;
9b34321999-12-19Henrik Grubbström (Grubba)  case T_FUNCTION: { struct program *prog;
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if (Pike_sp[-1].subtype == FUNCTION_BUILTIN) {
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode object type.\n");
9b34321999-12-19Henrik Grubbström (Grubba)  }
fc26f62000-07-06Fredrik Hübinette (Hubbe)  prog = program_from_svalue(Pike_sp-1);
9b34321999-12-19Henrik Grubbström (Grubba)  if (!prog) {
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode object type.\n");
9b34321999-12-19Henrik Grubbström (Grubba)  } push_type_int(prog->id); } break;
05590d1998-04-23Fredrik Hübinette (Hubbe)  default:
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode type "
4831891999-12-10Henrik Grubbström (Grubba)  "(object(%s), expected object(zero|program)).\n",
fc26f62000-07-06Fredrik Hübinette (Hubbe)  get_name_of_type(Pike_sp[-1].type));
05590d1998-04-23Fredrik Hübinette (Hubbe)  } pop_stack(); type_stack_reverse(); } }
770c7d1999-11-03Henrik Grubbström (Grubba)  UNSET_ONERROR(err2); UNSET_ONERROR(err1);
05590d1998-04-23Fredrik Hübinette (Hubbe) } /* This really needs to disable threads.... */ #define decode_type(X,data) do { \ type_stack_mark(); \ type_stack_mark(); \ low_decode_type(data); \ type_stack_reverse(); \ (X)=pop_unfinished_type(); \ } while(0)
50817d1997-10-07Fredrik Hübinette (Hubbe) 
3ad9861997-01-26Fredrik Hübinette (Hubbe) static void decode_value2(struct decode_data *data)
50817d1997-10-07Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
50817d1997-10-07Fredrik Hübinette (Hubbe) #undef decode_value2
fc26f62000-07-06Fredrik Hübinette (Hubbe) #define decode_value2(X) do { struct svalue *_=Pike_sp; decode_value2_(X); if(Pike_sp!=_+1) fatal("decode_value2 failed!\n"); } while(0)
50817d1997-10-07Fredrik Hübinette (Hubbe) #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe) {
be273a2000-09-11Henrik Grubbström (Grubba)  INT32 what, e, num, numh;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  struct svalue tmp, *tmp2;
583ade2000-02-16Per Hedbor 
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG data->depth += 2; #endif
52bb181999-10-25Fredrik Hübinette (Hubbe)  DECODE("decode_value2");
583ade2000-02-16Per Hedbor 
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG if(data->debug) { if((what & TAG_MASK ) == TAG_AGAIN) fprintf(stderr, "%*sDecoding TAG_AGAIN from <%d>\n", data->depth, "", num); else if(data->debug < 2) fprintf(stderr, "%*sDecoding to <%d>: TAG%d (%d)\n", data->depth, "", data->counter.u.integer , what & TAG_MASK, num); } #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe)  check_stack(1);
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  switch(what & TAG_MASK)
3ad9861997-01-26Fredrik Hübinette (Hubbe)  {
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_AGAIN:
50817d1997-10-07Fredrik Hübinette (Hubbe)  tmp.type=T_INT; tmp.subtype=0; tmp.u.integer=num; if((tmp2=low_mapping_lookup(data->decoded, &tmp))) { push_svalue(tmp2); }else{
27d61c2001-07-16Martin Stjernholm  Pike_error("Failed to decode TAG_AGAIN entry <%d>.\n", num);
50817d1997-10-07Fredrik Hübinette (Hubbe)  }
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG data->depth -= 2; #endif
50817d1997-10-07Fredrik Hübinette (Hubbe)  return;
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_INT:
50817d1997-10-07Fredrik Hübinette (Hubbe)  tmp=data->counter; data->counter.u.integer++; push_int(num); break;
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_STRING:
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  { struct pike_string *str;
50817d1997-10-07Fredrik Hübinette (Hubbe)  tmp=data->counter; data->counter.u.integer++;
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  get_string_data(str, num, data); push_string(str);
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  }
0dd0fa1999-12-11Henrik Grubbström (Grubba) 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_FLOAT:
3ad9861997-01-26Fredrik Hübinette (Hubbe)  {
11a87d2000-09-15Henrik Grubbström (Grubba)  double res;
583ade2000-02-16Per Hedbor 
27d61c2001-07-16Martin Stjernholm  EDB(2,fprintf(stderr, "Decoding float... numh:0x%08x, num:0x%08x\n",
be273a2000-09-11Henrik Grubbström (Grubba)  numh, num)); res = LDEXP((double)numh, 32) + (double)(unsigned INT32)num;
27d61c2001-07-16Martin Stjernholm  EDB(2,fprintf(stderr, "Mantissa: %10g\n", res));
be273a2000-09-11Henrik Grubbström (Grubba)  tmp = data->counter;
50817d1997-10-07Fredrik Hübinette (Hubbe)  data->counter.u.integer++;
583ade2000-02-16Per Hedbor 
52bb181999-10-25Fredrik Hübinette (Hubbe)  DECODE("float");
be273a2000-09-11Henrik Grubbström (Grubba) 
27d61c2001-07-16Martin Stjernholm  EDB(2,fprintf(stderr, "Exponent: %d\n", num));
be273a2000-09-11Henrik Grubbström (Grubba)  push_float(LDEXP(res, num));
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  }
69b77c1999-12-11Henrik Grubbström (Grubba) 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_TYPE:
69b77c1999-12-11Henrik Grubbström (Grubba)  {
7c29372001-04-19Henrik Grubbström (Grubba)  struct pike_string *t; decode_type(t, data); check_type_string(t); push_string(t); sp[-1].type = T_TYPE; tmp.type = T_INT; tmp = data->counter; data->counter.u.integer++;
69b77c1999-12-11Henrik Grubbström (Grubba)  }
7c29372001-04-19Henrik Grubbström (Grubba)  break;
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_ARRAY:
3ad9861997-01-26Fredrik Hübinette (Hubbe)  {
ab01ea1999-09-21Fredrik Hübinette (Hubbe)  struct array *a; if(num < 0)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode string. (array size is negative)\n");
ab01ea1999-09-21Fredrik Hübinette (Hubbe)  /* Heruetical */ if(data->ptr + num > data->len)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode array. (not enough data)\n");
ab01ea1999-09-21Fredrik Hübinette (Hubbe) 
50817d1997-10-07Fredrik Hübinette (Hubbe)  tmp.type=T_ARRAY;
ab01ea1999-09-21Fredrik Hübinette (Hubbe)  tmp.u.array=a=allocate_array(num);
27d61c2001-07-16Martin Stjernholm  EDB(2,fprintf(stderr, "%*sDecoding array of size %d to <%d>\n", data->depth, "", num, data->counter.u.integer));
50817d1997-10-07Fredrik Hübinette (Hubbe)  mapping_insert(data->decoded, & data->counter, &tmp); data->counter.u.integer++;
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  /* Since a reference to the array is stored in the mapping, we can * safely decrease this reference here. Thus it will be automatically * freed if something goes wrong. */ a->refs--;
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  for(e=0;e<num;e++) { decode_value2(data);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  ITEM(a)[e]=Pike_sp[-1]; Pike_sp--; dmalloc_touch_svalue(Pike_sp);
50817d1997-10-07Fredrik Hübinette (Hubbe)  }
d6ac731998-04-20Henrik Grubbström (Grubba)  ref_push_array(a);
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG data->depth -= 2; #endif
50817d1997-10-07Fredrik Hübinette (Hubbe)  return;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  }
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_MAPPING:
3ad9861997-01-26Fredrik Hübinette (Hubbe)  {
619d591997-12-22Fredrik Hübinette (Hubbe)  struct mapping *m; if(num<0)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode string. (mapping size is negative)\n");
619d591997-12-22Fredrik Hübinette (Hubbe) 
ab01ea1999-09-21Fredrik Hübinette (Hubbe)  /* Heruetical */ if(data->ptr + num > data->len)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode mapping. (not enough data)\n");
ab01ea1999-09-21Fredrik Hübinette (Hubbe) 
619d591997-12-22Fredrik Hübinette (Hubbe)  m=allocate_mapping(num);
50817d1997-10-07Fredrik Hübinette (Hubbe)  tmp.type=T_MAPPING; tmp.u.mapping=m;
27d61c2001-07-16Martin Stjernholm  EDB(2,fprintf(stderr, "%*sDecoding mapping of size %d to <%d>\n", data->depth, "", num, data->counter.u.integer));
50817d1997-10-07Fredrik Hübinette (Hubbe)  mapping_insert(data->decoded, & data->counter, &tmp); data->counter.u.integer++; m->refs--;
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  for(e=0;e<num;e++) { decode_value2(data); decode_value2(data);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  mapping_insert(m, Pike_sp-2, Pike_sp-1);
50817d1997-10-07Fredrik Hübinette (Hubbe)  pop_n_elems(2); }
d6ac731998-04-20Henrik Grubbström (Grubba)  ref_push_mapping(m);
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG data->depth -= 2; #endif
50817d1997-10-07Fredrik Hübinette (Hubbe)  return;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  }
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_MULTISET:
3ad9861997-01-26Fredrik Hübinette (Hubbe)  {
ab01ea1999-09-21Fredrik Hübinette (Hubbe)  struct multiset *m;
89cd7d2000-08-27Henrik Grubbström (Grubba)  struct array *a;
ab01ea1999-09-21Fredrik Hübinette (Hubbe)  if(num<0)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode string. (multiset size is negative)\n");
ab01ea1999-09-21Fredrik Hübinette (Hubbe)  /* Heruetical */ if(data->ptr + num > data->len)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode multiset. (not enough data)\n");
ab01ea1999-09-21Fredrik Hübinette (Hubbe) 
89cd7d2000-08-27Henrik Grubbström (Grubba)  /* NOTE: This code knows stuff about the implementation of multisets...*/ a = low_allocate_array(num, 0); m = allocate_multiset(a); tmp.type = T_MULTISET; tmp.u.multiset = m;
27d61c2001-07-16Martin Stjernholm  EDB(2,fprintf(stderr, "%*sDecoding multiset of size %d to <%d>\n", data->depth, "", num, data->counter.u.integer));
50817d1997-10-07Fredrik Hübinette (Hubbe)  mapping_insert(data->decoded, & data->counter, &tmp); data->counter.u.integer++;
770c7d1999-11-03Henrik Grubbström (Grubba)  debug_malloc_touch(m);
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  for(e=0;e<num;e++) { decode_value2(data);
89cd7d2000-08-27Henrik Grubbström (Grubba)  a->item[e] = sp[-1]; sp--; dmalloc_touch_svalue(sp);
50817d1997-10-07Fredrik Hübinette (Hubbe)  }
89cd7d2000-08-27Henrik Grubbström (Grubba)  array_fix_type_field(a); order_multiset(m); push_multiset(m);
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG data->depth -= 2; #endif
50817d1997-10-07Fredrik Hübinette (Hubbe)  return;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  }
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_OBJECT:
27d61c2001-07-16Martin Stjernholm  {
50817d1997-10-07Fredrik Hübinette (Hubbe)  tmp=data->counter; data->counter.u.integer++;
27d61c2001-07-16Martin Stjernholm 
50817d1997-10-07Fredrik Hübinette (Hubbe)  decode_value2(data);
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  switch(num) { case 0:
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(data->codec) { apply(data->codec,"objectof", 1); }else{
9cba792001-01-25Fredrik Hübinette (Hubbe)  fallback_codec();
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  case 1:
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(IS_ZERO(Pike_sp-1))
50817d1997-10-07Fredrik Hübinette (Hubbe)  {
27d61c2001-07-16Martin Stjernholm  EDB(1,fprintf(stderr, "%*sDecoded a failed object to <%d>: ", data->depth, "", tmp.u.integer); print_svalue(stderr, Pike_sp-1); fputc('\n', stderr););
50817d1997-10-07Fredrik Hübinette (Hubbe)  decode_value2(data); pop_stack(); }else{
27d61c2001-07-16Martin Stjernholm  struct object *o; /* decode_value_clone_object does not call __INIT, so * we want to do that ourselves... */ o=decode_value_clone_object(Pike_sp-1); debug_malloc_touch(o); pop_stack(); push_object(o); if(o->prog) { if(o->prog->flags & PROGRAM_FINISHED) { apply_lfun(o, LFUN___INIT, 0); pop_stack();
0f8f572001-07-16Martin Stjernholm  apply_lfun(o,LFUN_CREATE, 0); pop_stack();
27d61c2001-07-16Martin Stjernholm  }else{ struct unfinished_obj_link *ol=ALLOC_STRUCT(unfinished_obj_link); ol->o=o; ol->next=data->unfinished_objects; data->unfinished_objects=ol; } } EDB(2,fprintf(stderr, "%*sDecoded an object to <%d>: ", data->depth, "", tmp.u.integer); print_svalue(stderr, Pike_sp-1); fputc('\n', stderr);); ref_push_object(o);
50817d1997-10-07Fredrik Hübinette (Hubbe)  decode_value2(data);
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(!data->codec)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode (no codec)\n");
05590d1998-04-23Fredrik Hübinette (Hubbe)  apply(data->codec,"decode_object",2);
50817d1997-10-07Fredrik Hübinette (Hubbe)  pop_stack(); }
27d61c2001-07-16Martin Stjernholm  break;
52bb181999-10-25Fredrik Hübinette (Hubbe)  #ifdef AUTO_BIGNUM /* It is possible that we should do this even without * AUTO_BIGNUM /Hubbe * However, that requires that some of the bignum functions * are always available... */ case 2: { check_stack(2); /* 256 would be better, but then negative numbers * doesn't work... /Hubbe */ push_int(36); convert_stack_top_with_base_to_bignum(); break; } #endif
27d61c2001-07-16Martin Stjernholm  case 3: pop_stack(); decode_value2(data); break;
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  default:
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Object coding not compatible.\n");
50817d1997-10-07Fredrik Hübinette (Hubbe)  break; }
27d61c2001-07-16Martin Stjernholm  if(Pike_sp[-1].type != T_OBJECT) if(data->pickyness) Pike_error("Failed to decode object.\n");
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
27d61c2001-07-16Martin Stjernholm  }
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_FUNCTION:
50817d1997-10-07Fredrik Hübinette (Hubbe)  tmp=data->counter; data->counter.u.integer++; decode_value2(data);
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  switch(num) { case 0:
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(data->codec) { apply(data->codec,"functionof", 1); }else{
9cba792001-01-25Fredrik Hübinette (Hubbe)  fallback_codec();
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  case 1: decode_value2(data);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp[-2].type==T_INT)
5f06241999-04-11Fredrik Hübinette (Hubbe)  { pop_stack(); }else{ f_arrow(2); }
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  default:
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Function coding not compatible.\n");
50817d1997-10-07Fredrik Hübinette (Hubbe)  break; }
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(data->pickyness && Pike_sp[-1].type != T_FUNCTION)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode function.\n");
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_PROGRAM:
05590d1998-04-23Fredrik Hübinette (Hubbe)  switch(num) { case 0:
82d47c1999-11-04Henrik Grubbström (Grubba)  { struct svalue *prog_code;
05590d1998-04-23Fredrik Hübinette (Hubbe)  tmp=data->counter; data->counter.u.integer++; decode_value2(data);
82d47c1999-11-04Henrik Grubbström (Grubba) 
a4a1722000-12-05Per Hedbor  /* Keep the value so that we can make a good error-message. */
fc26f62000-07-06Fredrik Hübinette (Hubbe)  prog_code = Pike_sp-1;
82d47c1999-11-04Henrik Grubbström (Grubba)  stack_dup();
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(data->codec) { apply(data->codec,"programof", 1); }else{
9cba792001-01-25Fredrik Hübinette (Hubbe)  fallback_codec();
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(data->pickyness && !program_from_svalue(Pike_sp-1)) {
82d47c1999-11-04Henrik Grubbström (Grubba)  if ((prog_code->type == T_STRING) && (prog_code->u.string->len < 128) && (!prog_code->u.string->size_shift)) {
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode program \"%s\".\n",
82d47c1999-11-04Henrik Grubbström (Grubba)  prog_code->u.string->str); }
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode program.\n");
82d47c1999-11-04Henrik Grubbström (Grubba)  } /* Remove the extra entry from the stack. */ stack_swap(); pop_stack();
05590d1998-04-23Fredrik Hübinette (Hubbe)  break;
82d47c1999-11-04Henrik Grubbström (Grubba)  }
05590d1998-04-23Fredrik Hübinette (Hubbe)  case 1: { int d;
f00c362000-08-10Henrik Grubbström (Grubba)  size_t size=0;
05590d1998-04-23Fredrik Hübinette (Hubbe)  char *dat; struct program *p;
27d61c2001-07-16Martin Stjernholm  ONERROR err1, err2, err3;
05590d1998-04-23Fredrik Hübinette (Hubbe) 
928ad61998-04-27Fredrik Hübinette (Hubbe) #ifdef _REENTRANT ONERROR err;
f8d8cf1999-07-18Fredrik Hübinette (Hubbe)  low_init_threads_disable();
928ad61998-04-27Fredrik Hübinette (Hubbe)  SET_ONERROR(err, do_enable_threads, 0); #endif
05590d1998-04-23Fredrik Hübinette (Hubbe)  p=low_allocate_program();
27d61c2001-07-16Martin Stjernholm  SET_ONERROR(err3, zap_unfinished_program, p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  debug_malloc_touch(p); tmp.type=T_PROGRAM; tmp.u.program=p;
27d61c2001-07-16Martin Stjernholm  EDB(2,fprintf(stderr, "%*sDecoding a program to <%d>: ", data->depth, "", data->counter.u.integer); print_svalue(stderr, &tmp); fputc('\n', stderr););
05590d1998-04-23Fredrik Hübinette (Hubbe)  mapping_insert(data->decoded, & data->counter, &tmp); data->counter.u.integer++; p->refs--;
583ade2000-02-16Per Hedbor 
a757011998-05-16Fredrik Hübinette (Hubbe)  decode_value2(data); f_version(0);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(!is_eq(Pike_sp-1,Pike_sp-2))
a4a1722000-12-05Per Hedbor  Pike_error("Cannot decode programs encoded with other pike version.\n");
a757011998-05-16Fredrik Hübinette (Hubbe)  pop_n_elems(2);
27d61c2001-07-16Martin Stjernholm  debug_malloc_touch(p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  decode_number(p->flags,data);
27d61c2001-07-16Martin Stjernholm  p->flags &= ~(PROGRAM_FINISHED | PROGRAM_OPTIMIZED | PROGRAM_FIXED | PROGRAM_PASS_1_DONE);
8ba59a2000-03-26Fredrik Hübinette (Hubbe)  p->flags |= PROGRAM_AVOID_CHECK;
05590d1998-04-23Fredrik Hübinette (Hubbe)  decode_number(p->storage_needed,data);
8f29a31999-09-15Fredrik Hübinette (Hubbe)  decode_number(p->alignment_needed,data);
05590d1998-04-23Fredrik Hübinette (Hubbe)  decode_number(p->timestamp.tv_sec,data); decode_number(p->timestamp.tv_usec,data);
27d61c2001-07-16Martin Stjernholm  debug_malloc_touch(p);
05590d1998-04-23Fredrik Hübinette (Hubbe) #define FOO(X,Y,Z) \ decode_number( p->num_##Z, data); #include "program_areas.h"
583ade2000-02-16Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe) #define FOO(NUMTYPE,TYPE,NAME) \ size=DO_ALIGN(size, ALIGNOF(TYPE)); \ size+=p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0]); #include "program_areas.h" dat=xalloc(size); debug_malloc_touch(dat); MEMSET(dat,0,size); size=0; #define FOO(NUMTYPE,TYPE,NAME) \ size=DO_ALIGN(size, ALIGNOF(TYPE)); \ p->NAME=(TYPE *)(dat+size); \ size+=p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0]); #include "program_areas.h" for(e=0;e<p->num_constants;e++)
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  p->constants[e].sval.type=T_INT;
05590d1998-04-23Fredrik Hübinette (Hubbe)  debug_malloc_touch(dat);
27d61c2001-07-16Martin Stjernholm  debug_malloc_touch(p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  p->total_size=size + sizeof(struct program); p->flags |= PROGRAM_OPTIMIZED; getdata2(p->program, p->num_program); getdata2(p->linenumbers, p->num_linenumbers);
aaec3f1999-10-18Fredrik Hübinette (Hubbe) #ifdef DEBUG_MALLOC if(p->num_linenumbers && p->linenumbers &&
58ef5e1999-10-19Fredrik Hübinette (Hubbe)  EXTRACT_UCHAR(p->linenumbers)==127) { char *foo; extern int get_small_number(char **); foo=p->linenumbers+1; foo+=strlen(foo)+1;
bb987a1999-10-19Fredrik Hübinette (Hubbe)  get_small_number(&foo); /* pc offset */
583ade2000-02-16Per Hedbor  debug_malloc_name(p, p->linenumbers+1,
58ef5e1999-10-19Fredrik Hübinette (Hubbe)  get_small_number(&foo)); }
aaec3f1999-10-18Fredrik Hübinette (Hubbe) #endif
583ade2000-02-16Per Hedbor 
aaec3f1999-10-18Fredrik Hübinette (Hubbe) 
27d61c2001-07-16Martin Stjernholm  debug_malloc_touch(p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  for(d=0;d<p->num_identifier_index;d++) { decode_number(p->identifier_index[d],data); if(p->identifier_index[d] > p->num_identifier_references) { p->identifier_index[d]=0;
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Malformed program in decode.\n");
05590d1998-04-23Fredrik Hübinette (Hubbe)  } }
583ade2000-02-16Per Hedbor 
27d61c2001-07-16Martin Stjernholm  debug_malloc_touch(p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  for(d=0;d<p->num_variable_index;d++) { decode_number(p->variable_index[d],data); if(p->variable_index[d] > p->num_identifiers) { p->variable_index[d]=0;
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Malformed program in decode.\n");
05590d1998-04-23Fredrik Hübinette (Hubbe)  } }
583ade2000-02-16Per Hedbor 
27d61c2001-07-16Martin Stjernholm  debug_malloc_touch(p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  for(d=0;d<p->num_identifier_references;d++) { decode_number(p->identifier_references[d].inherit_offset,data); if(p->identifier_references[d].inherit_offset > p->num_inherits) { p->identifier_references[d].inherit_offset=0;
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Malformed program in decode.\n");
05590d1998-04-23Fredrik Hübinette (Hubbe)  } decode_number(p->identifier_references[d].identifier_offset,data); decode_number(p->identifier_references[d].id_flags,data);
27d61c2001-07-16Martin Stjernholm  EDB(3,fprintf(stderr,"IDREF%x < %d: { %d, %d, %d }\n", p->id,d, p->identifier_references[d].inherit_offset, p->identifier_references[d].identifier_offset, p->identifier_references[d].id_flags); );
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
583ade2000-02-16Per Hedbor 
27d61c2001-07-16Martin Stjernholm  debug_malloc_touch(p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  for(d=0;d<p->num_strings;d++) getdata(p->strings[d]);
27d61c2001-07-16Martin Stjernholm  debug_malloc_touch(p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  debug_malloc_touch(dat); data->pickyness++;
6c15501999-09-19Fredrik Hübinette (Hubbe) 
583ade2000-02-16Per Hedbor 
2ad3c01999-09-16Fredrik Hübinette (Hubbe) /* p->inherits[0].prog=p;
05590d1998-04-23Fredrik Hübinette (Hubbe)  p->inherits[0].parent_offset=1;
2ad3c01999-09-16Fredrik Hübinette (Hubbe) */
05590d1998-04-23Fredrik Hübinette (Hubbe) 
27d61c2001-07-16Martin Stjernholm  debug_malloc_touch(p);
2ad3c01999-09-16Fredrik Hübinette (Hubbe)  for(d=0;d<p->num_inherits;d++)
05590d1998-04-23Fredrik Hübinette (Hubbe)  { decode_number(p->inherits[d].inherit_level,data); decode_number(p->inherits[d].identifier_level,data); decode_number(p->inherits[d].parent_offset,data);
b182582000-09-30Fredrik Hübinette (Hubbe)  decode_number(p->inherits[d].parent_identifier,data);
05590d1998-04-23Fredrik Hübinette (Hubbe)  decode_number(p->inherits[d].storage_offset,data);
583ade2000-02-16Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  decode_value2(data);
6c15501999-09-19Fredrik Hübinette (Hubbe)  if(d==0) {
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].type != T_PROGRAM || Pike_sp[-1].u.program != p)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Program decode failed!\n");
6c15501999-09-19Fredrik Hübinette (Hubbe)  p->refs--; }
583ade2000-02-16Per Hedbor 
fc26f62000-07-06Fredrik Hübinette (Hubbe)  switch(Pike_sp[-1].type)
05590d1998-04-23Fredrik Hübinette (Hubbe)  { case T_FUNCTION:
fc26f62000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].subtype == FUNCTION_BUILTIN)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode parent.\n");
583ade2000-02-16Per Hedbor 
27d61c2001-07-16Martin Stjernholm  EDB(3, fprintf(stderr,"INHERIT%x = func { %p, %d} \n",p->id,Pike_sp[-1].u.object, Pike_sp[-1].subtype); );
fc26f62000-07-06Fredrik Hübinette (Hubbe)  p->inherits[d].parent_identifier=Pike_sp[-1].subtype; p->inherits[d].prog=program_from_svalue(Pike_sp-1);
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(!p->inherits[d].prog)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode parent.\n");
05590d1998-04-23Fredrik Hübinette (Hubbe)  add_ref(p->inherits[d].prog);
fc26f62000-07-06Fredrik Hübinette (Hubbe)  p->inherits[d].parent=Pike_sp[-1].u.object; Pike_sp--; dmalloc_touch_svalue(Pike_sp);
05590d1998-04-23Fredrik Hübinette (Hubbe)  break; case T_PROGRAM:
27d61c2001-07-16Martin Stjernholm  EDB(3, fprintf(stderr,"INHERIT%x = prog\n",p->id); );
fc26f62000-07-06Fredrik Hübinette (Hubbe)  p->inherits[d].prog=Pike_sp[-1].u.program; Pike_sp--; dmalloc_touch_svalue(Pike_sp);
05590d1998-04-23Fredrik Hübinette (Hubbe)  break; default:
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to decode inheritance.\n");
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
583ade2000-02-16Per Hedbor 
11b69f1999-09-17Fredrik Hübinette (Hubbe)  getdata3(p->inherits[d].name);
27d61c2001-07-16Martin Stjernholm  EDB(3, fprintf(stderr,"INHERIT%x < %d: %d id=%d\n", p->id,d, p->inherits[d].prog->num_identifiers, p->inherits[d].prog->id); );
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
583ade2000-02-16Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  debug_malloc_touch(dat);
27d61c2001-07-16Martin Stjernholm 
bad5162000-06-23Fredrik Hübinette (Hubbe)  SET_ONERROR(err1, restore_type_stack, Pike_compiler->type_stackp); SET_ONERROR(err2, restore_type_mark, Pike_compiler->pike_type_mark_stackp);
770c7d1999-11-03Henrik Grubbström (Grubba) 
27d61c2001-07-16Martin Stjernholm  debug_malloc_touch(p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  for(d=0;d<p->num_identifiers;d++) { getdata(p->identifiers[d].name); decode_type(p->identifiers[d].type,data); decode_number(p->identifiers[d].identifier_flags,data); decode_number(p->identifiers[d].run_time_type,data);
5e84532000-08-30Fredrik Hübinette (Hubbe)  decode_number(p->identifiers[d].opt_flags,data);
27d61c2001-07-16Martin Stjernholm  if (!(p->identifiers[d].identifier_flags & IDENTIFIER_C_FUNCTION)) { decode_number(p->identifiers[d].func.offset,data); } else { Pike_error("Cannot decode functions implemented in C " "(identifier='%s').\n", p->identifiers[d].name->str); }
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
27d61c2001-07-16Martin Stjernholm 
770c7d1999-11-03Henrik Grubbström (Grubba)  UNSET_ONERROR(err2); UNSET_ONERROR(err1);
05590d1998-04-23Fredrik Hübinette (Hubbe)  debug_malloc_touch(dat);
583ade2000-02-16Per Hedbor 
27d61c2001-07-16Martin Stjernholm  debug_malloc_touch(p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  for(d=0;d<NUM_LFUNS;d++) decode_number(p->lfuns[d],data); debug_malloc_touch(dat);
583ade2000-02-16Per Hedbor 
27d61c2001-07-16Martin Stjernholm  debug_malloc_touch(p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  {
bad5162000-06-23Fredrik Hübinette (Hubbe)  struct program *new_program_save=Pike_compiler->new_program; Pike_compiler->new_program=p;
05590d1998-04-23Fredrik Hübinette (Hubbe)  fsort((void *)p->identifier_index, p->num_identifier_index, sizeof(unsigned short),(fsortfun)program_function_index_compare);
bad5162000-06-23Fredrik Hübinette (Hubbe)  Pike_compiler->new_program=new_program_save;
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
27d61c2001-07-16Martin Stjernholm  debug_malloc_touch(dat); debug_malloc_touch(p); p->flags |= PROGRAM_PASS_1_DONE | PROGRAM_FIXED; for(d=0;d<p->num_constants;d++) { decode_value2(data); p->constants[d].sval=*--Pike_sp; dmalloc_touch_svalue(Pike_sp); getdata3(p->constants[d].name); } data->pickyness--; UNSET_ONERROR(err3);
05590d1998-04-23Fredrik Hübinette (Hubbe)  ref_push_program(p);
928ad61998-04-27Fredrik Hübinette (Hubbe) 
27d61c2001-07-16Martin Stjernholm  /* Logic for the PROGRAM_FINISHED flag: * The purpose of this code is to make sure that the PROGRAM_FINISHED * flat is not set on the program until all inherited programs also * have that flag. -Hubbe */ for(d=1;d<p->num_inherits;d++) if(! (p->inherits[d].prog->flags & PROGRAM_FINISHED)) break; if(d == p->num_inherits) { p->flags &=~ PROGRAM_AVOID_CHECK; p->flags |= PROGRAM_FINISHED; /* Go through the linked list of unfinished programs * to see what programs are now finished. */ { struct unfinished_prog_link *l, **ptr;
770c7d1999-11-03Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG
27d61c2001-07-16Martin Stjernholm  check_program(p);
770c7d1999-11-03Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
27d61c2001-07-16Martin Stjernholm  /* It is possible that we need to restart loop * in some cases... /Hubbe */ for(ptr= &data->unfinished_programs ; (l=*ptr);) { struct program *pp=l->prog; for(d=1;d<pp->num_inherits;d++) if(! (pp->inherits[d].prog->flags & PROGRAM_FINISHED)) break; if(d == pp->num_inherits) { pp->flags &=~ PROGRAM_AVOID_CHECK; pp->flags |= PROGRAM_FINISHED; #ifdef PIKE_DEBUG check_program(pp); #endif /* PIKE_DEBUG */ *ptr = l->next; free((char *)l); }else{ ptr=&l->next; } } } /* Go through the linked list of unfinished objects * to see what objects are now finished. */ { struct unfinished_obj_link *l, **ptr; for(ptr= &data->unfinished_objects ; (l=*ptr);) { struct object *o=l->o; if(o->prog) { if(o->prog->flags & PROGRAM_FINISHED) { apply_lfun(o, LFUN___INIT, 0); pop_stack();
23179d2001-07-16Martin Stjernholm  apply_lfun(o,LFUN_CREATE, 0); pop_stack();
27d61c2001-07-16Martin Stjernholm  }else{ ptr=&l->next; continue; } } *ptr = l->next; free((char *)l); } } }else{ struct unfinished_prog_link *l; l=ALLOC_STRUCT(unfinished_prog_link); l->prog=p; l->next=data->unfinished_programs; data->unfinished_programs=l; }
928ad61998-04-27Fredrik Hübinette (Hubbe) #ifdef _REENTRANT UNSET_ONERROR(err);
f8d8cf1999-07-18Fredrik Hübinette (Hubbe)  exit_threads_disable(NULL);
928ad61998-04-27Fredrik Hübinette (Hubbe) #endif
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG data->depth -= 2; #endif
05590d1998-04-23Fredrik Hübinette (Hubbe)  return; } default:
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot decode program encoding type %d\n",num);
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  default:
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Failed to restore string. (Illegal type)\n");
3ad9861997-01-26Fredrik Hübinette (Hubbe)  }
27d61c2001-07-16Martin Stjernholm  EDB(2,fprintf(stderr, "%*sDecoded to <%d>: ", data->depth, "", tmp.u.integer); print_svalue(stderr, Pike_sp-1); fputc('\n', stderr););
fc26f62000-07-06Fredrik Hübinette (Hubbe)  mapping_insert(data->decoded, & tmp, Pike_sp-1);
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG data->depth -= 2; #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe) }
27d61c2001-07-16Martin Stjernholm static struct decode_data *current_decode = NULL;
3ad9861997-01-26Fredrik Hübinette (Hubbe) static void free_decode_data(struct decode_data *data) { free_mapping(data->decoded);
27d61c2001-07-16Martin Stjernholm  while(data->unfinished_programs) { struct unfinished_prog_link *tmp=data->unfinished_programs; data->unfinished_programs=tmp->next; free((char *)tmp); } while(data->unfinished_objects) { struct unfinished_obj_link *tmp=data->unfinished_objects; data->unfinished_objects=tmp->next; free((char *)tmp); } if (current_decode == data) { current_decode = data->next; } else { struct decode_data *d; for (d = current_decode; d; d=d->next) { if (d->next == data) { d->next = d->next->next; break; } } #ifdef PIKE_DEBUG if (!d) { fatal("Decode data fell off the stack!\n"); } #endif /* PIKE_DEBUG */ }
41fbc12001-08-14Martin Stjernholm #ifdef PIKE_THREADS free_object(data->thread_id); #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe) }
05590d1998-04-23Fredrik Hübinette (Hubbe) static INT32 my_decode(struct pike_string *tmp,
27d61c2001-07-16Martin Stjernholm  struct object *codec #ifdef ENCODE_DEBUG , int debug #endif )
3ad9861997-01-26Fredrik Hübinette (Hubbe) { ONERROR err; struct decode_data d, *data;
27d61c2001-07-16Martin Stjernholm  /* Attempt to avoid infinite recursion on circular structures. */ for (data = current_decode; data; data=data->next) {
41fbc12001-08-14Martin Stjernholm  if (data->raw == tmp && data->codec == codec #ifdef PIKE_THREADS && data->thread_id == Pike_interpreter.thread_id #endif ) {
27d61c2001-07-16Martin Stjernholm  struct svalue *res; struct svalue val = { T_INT, NUMBER_NUMBER, };
41fbc12001-08-14Martin Stjernholm  val.u.integer = COUNTER_START;
27d61c2001-07-16Martin Stjernholm  if ((res = low_mapping_lookup(data->decoded, &val))) { push_svalue(res); return 1; } /* Possible recursion detected. */ /* return 0; */ } }
3ad9861997-01-26Fredrik Hübinette (Hubbe)  data=&d; data->counter.type=T_INT; data->counter.u.integer=COUNTER_START;
04554a1997-04-10Fredrik Hübinette (Hubbe)  data->data=(unsigned char *)tmp->str;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  data->len=tmp->len; data->ptr=0;
05590d1998-04-23Fredrik Hübinette (Hubbe)  data->codec=codec; data->pickyness=0;
27d61c2001-07-16Martin Stjernholm  data->unfinished_programs=0; data->unfinished_objects=0; data->raw = tmp; data->next = current_decode;
41fbc12001-08-14Martin Stjernholm #ifdef PIKE_THREADS data->thread_id = Pike_interpreter.thread_id; add_ref(Pike_interpreter.thread_id); #endif
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG data->debug = debug; data->depth = -2; #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe) 
ff88671999-09-22Henrik Grubbström (Grubba)  if (tmp->size_shift) return 0;
9d21f91997-01-27Fredrik Hübinette (Hubbe)  if(data->len < 5) return 0;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  if(GETC() != 182 || GETC() != 'k' || GETC() != 'e' || GETC() != '0') return 0; data->decoded=allocate_mapping(128);
27d61c2001-07-16Martin Stjernholm  current_decode = data;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  SET_ONERROR(err, free_decode_data, data); decode_value2(data);
27d61c2001-07-16Martin Stjernholm  #ifdef PIKE_DEBUG if(data->unfinished_programs) fatal("We have unfinished programs left in decode()!\n"); if(data->unfinished_objects) fatal("We have unfinished objects left in decode()!\n"); #endif CALL_AND_UNSET_ONERROR(err);
3ad9861997-01-26Fredrik Hübinette (Hubbe)  return 1; } /* Compatibilidy decoder */
393a592000-08-16Henrik Grubbström (Grubba) static unsigned char extract_char(char **v, ptrdiff_t *l)
3ad9861997-01-26Fredrik Hübinette (Hubbe) {
a4a1722000-12-05Per Hedbor  if(!*l) Pike_error("Format error, not enough place for char.\n");
3ad9861997-01-26Fredrik Hübinette (Hubbe)  else (*l)--; (*v)++; return ((unsigned char *)(*v))[-1]; }
393a592000-08-16Henrik Grubbström (Grubba) static ptrdiff_t extract_int(char **v, ptrdiff_t *l)
3ad9861997-01-26Fredrik Hübinette (Hubbe) {
c7241b2000-08-10Henrik Grubbström (Grubba)  INT32 j; ptrdiff_t i;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  j=extract_char(v,l); if(j & 0x80) return (j & 0x7f); if((j & ~8) > 4)
a4a1722000-12-05Per Hedbor  Pike_error("Format error: Error in format string, invalid integer.\n");
3ad9861997-01-26Fredrik Hübinette (Hubbe)  i=0; while(j & 7) { i=(i<<8) | extract_char(v,l); j--; } if(j & 8) return -i; return i; }
393a592000-08-16Henrik Grubbström (Grubba) static void rec_restore_value(char **v, ptrdiff_t *l)
3ad9861997-01-26Fredrik Hübinette (Hubbe) {
f00c362000-08-10Henrik Grubbström (Grubba)  ptrdiff_t t, i;
3ad9861997-01-26Fredrik Hübinette (Hubbe) 
f00c362000-08-10Henrik Grubbström (Grubba)  i = extract_int(v,l); t = extract_int(v,l);
3ad9861997-01-26Fredrik Hübinette (Hubbe)  switch(i) {
f00c362000-08-10Henrik Grubbström (Grubba)  case TAG_INT: push_int(DO_NOT_WARN(t)); return;
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_FLOAT:
f00c362000-08-10Henrik Grubbström (Grubba)  if(sizeof(ptrdiff_t) < sizeof(FLOAT_TYPE)) /* FIXME FIXME FIXME FIXME */
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Float architecture not supported.\n");
f00c362000-08-10Henrik Grubbström (Grubba)  push_int(DO_NOT_WARN(t)); /* WARNING! */
fc26f62000-07-06Fredrik Hübinette (Hubbe)  Pike_sp[-1].type = T_FLOAT;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  return;
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_TYPE:
a4a1722000-12-05Per Hedbor  Pike_error("Format error: decoding of the type type not supported yet.\n");
69b77c1999-12-11Henrik Grubbström (Grubba)  return;
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_STRING:
a4a1722000-12-05Per Hedbor  if(t<0) Pike_error("Format error: length of string is negative.\n"); if(*l < t) Pike_error("Format error: string to short\n");
3ad9861997-01-26Fredrik Hübinette (Hubbe)  push_string(make_shared_binary_string(*v, t));
f00c362000-08-10Henrik Grubbström (Grubba)  (*l)-= t; (*v)+= t;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  return;
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_ARRAY:
a4a1722000-12-05Per Hedbor  if(t<0) Pike_error("Format error: length of array is negative.\n");
3ad9861997-01-26Fredrik Hübinette (Hubbe)  check_stack(t); for(i=0;i<t;i++) rec_restore_value(v,l);
e0755c2000-08-15Henrik Grubbström (Grubba)  f_aggregate(DO_NOT_WARN(t));
3ad9861997-01-26Fredrik Hübinette (Hubbe)  return;
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_MULTISET:
a4a1722000-12-05Per Hedbor  if(t<0) Pike_error("Format error: length of multiset is negative.\n");
3ad9861997-01-26Fredrik Hübinette (Hubbe)  check_stack(t); for(i=0;i<t;i++) rec_restore_value(v,l);
e0755c2000-08-15Henrik Grubbström (Grubba)  f_aggregate_multiset(DO_NOT_WARN(t));
3ad9861997-01-26Fredrik Hübinette (Hubbe)  return;
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_MAPPING:
a4a1722000-12-05Per Hedbor  if(t<0) Pike_error("Format error: length of mapping is negative.\n");
3ad9861997-01-26Fredrik Hübinette (Hubbe)  check_stack(t*2); for(i=0;i<t;i++) { rec_restore_value(v,l); rec_restore_value(v,l); }
e0755c2000-08-15Henrik Grubbström (Grubba)  f_aggregate_mapping(DO_NOT_WARN(t*2));
3ad9861997-01-26Fredrik Hübinette (Hubbe)  return;
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_OBJECT:
a4a1722000-12-05Per Hedbor  if(t<0) Pike_error("Format error: length of object is negative.\n"); if(*l < t) Pike_error("Format error: string to short\n");
3ad9861997-01-26Fredrik Hübinette (Hubbe)  push_string(make_shared_binary_string(*v, t)); (*l) -= t; (*v) += t; APPLY_MASTER("objectof", 1); return;
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_FUNCTION:
a4a1722000-12-05Per Hedbor  if(t<0) Pike_error("Format error: length of function is negative.\n"); if(*l < t) Pike_error("Format error: string to short\n");
3ad9861997-01-26Fredrik Hübinette (Hubbe)  push_string(make_shared_binary_string(*v, t)); (*l) -= t; (*v) += t; APPLY_MASTER("functionof", 1); return;
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_PROGRAM:
a4a1722000-12-05Per Hedbor  if(t<0) Pike_error("Format error: length of program is negative.\n"); if(*l < t) Pike_error("Format error: string to short\n");
3ad9861997-01-26Fredrik Hübinette (Hubbe)  push_string(make_shared_binary_string(*v, t)); (*l) -= t; (*v) += t; APPLY_MASTER("programof", 1); return;
583ade2000-02-16Per Hedbor 
3ad9861997-01-26Fredrik Hübinette (Hubbe)  default:
a4a1722000-12-05Per Hedbor  Pike_error("Format error: Unknown type tag %ld:%ld\n",
6f95902000-08-17Henrik Grubbström (Grubba)  PTRDIFF_T_TO_LONG(i), PTRDIFF_T_TO_LONG(t));
3ad9861997-01-26Fredrik Hübinette (Hubbe)  } } void f_decode_value(INT32 args) { struct pike_string *s;
05590d1998-04-23Fredrik Hübinette (Hubbe)  struct object *codec;
3ad9861997-01-26Fredrik Hübinette (Hubbe) 
27d61c2001-07-16Martin Stjernholm #ifdef ENCODE_DEBUG int debug; check_all_args("decode_value", args, BIT_STRING, BIT_VOID | BIT_OBJECT | BIT_INT, BIT_VOID | BIT_INT, 0); debug = args > 2 ? Pike_sp[2-args].u.integer : 0; #else
ff88671999-09-22Henrik Grubbström (Grubba)  check_all_args("decode_value", args, BIT_STRING, BIT_VOID | BIT_OBJECT | BIT_INT, 0);
27d61c2001-07-16Martin Stjernholm #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe) 
fc26f62000-07-06Fredrik Hübinette (Hubbe)  s = Pike_sp[-args].u.string;
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(args<2) { codec=get_master(); }
fc26f62000-07-06Fredrik Hübinette (Hubbe)  else if(Pike_sp[1-args].type == T_OBJECT)
05590d1998-04-23Fredrik Hübinette (Hubbe)  {
fc26f62000-07-06Fredrik Hübinette (Hubbe)  codec=Pike_sp[1-args].u.object;
05590d1998-04-23Fredrik Hübinette (Hubbe)  } else { codec=0; }
27d61c2001-07-16Martin Stjernholm  if(!my_decode(s, codec #ifdef ENCODE_DEBUG , debug #endif ))
3ad9861997-01-26Fredrik Hübinette (Hubbe)  { char *v=s->str;
e0755c2000-08-15Henrik Grubbström (Grubba)  ptrdiff_t l=s->len;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  rec_restore_value(&v, &l); }
fc26f62000-07-06Fredrik Hübinette (Hubbe)  assign_svalue(Pike_sp-args-1, Pike_sp-1);
3ad9861997-01-26Fredrik Hübinette (Hubbe)  pop_n_elems(args); }