e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */
aedfb12002-10-09Martin Nilsson 
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"
2479e92003-08-05Henrik Grubbström (Grubba) #include "lex.h"
3ad9861997-01-26Fredrik Hübinette (Hubbe) #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"
d8e19a2002-04-07Martin Stjernholm #include "pikecode.h"
a0180b2003-11-14Martin Stjernholm #include "pike_types.h"
6b06d82003-11-17Henrik Grubbström (Grubba) #include "opcodes.h"
82723d2003-11-25Henrik Grubbström (Grubba) #include "peep.h"
e021fe2008-04-14Henrik Grubbström (Grubba) #include "pike_compiler.h"
1db77c2014-01-11Tobias S. Josefowitz #include "bitvector.h"
3ad9861997-01-26Fredrik Hübinette (Hubbe) 
a696672005-11-20Henrik Grubbström (Grubba) /* #define ENCODE_DEBUG */
52bb181999-10-25Fredrik Hübinette (Hubbe) 
9182912002-05-10Henrik Grubbström (Grubba) /* Use the old encoding method for programs. */
388ca32003-02-24Martin Stjernholm /* #define OLD_PIKE_ENCODE_PROGRAM */
9182912002-05-10Henrik Grubbström (Grubba) 
52bb181999-10-25Fredrik Hübinette (Hubbe) #ifdef ENCODE_DEBUG
b55a122001-07-10Martin Stjernholm /* Pass a nonzero integer as the third arg to encode_value,
c2b4592010-11-22Martin Stjernholm  * encode_value_canonic and decode_value to activate this debug. It * both enables debug messages and also lessens the pickyness to * sort-of be able to decode programs with the wrong codec. */
997a002001-11-08Fredrik Hübinette (Hubbe) #define EDB(N,X) do { debug_malloc_touch(data); if (data->debug>=N) {X;} } while (0)
6b12402003-06-04Martin Nilsson #ifndef PIKE_DEBUG #error ENCODE_DEBUG requires PIKE_DEBUG #endif
52bb181999-10-25Fredrik Hübinette (Hubbe) #else
997a002001-11-08Fredrik Hübinette (Hubbe) #define EDB(N,X) do { debug_malloc_touch(data); } while (0)
52bb181999-10-25Fredrik Hübinette (Hubbe) #endif
24ddc71998-03-28Henrik Grubbström (Grubba) 
3ad9861997-01-26Fredrik Hübinette (Hubbe) #ifdef _AIX #include <net/nh.h> #endif #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif
abfed12003-12-17Marcus Comstedt #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> #endif
ae8b342001-08-11Henrik Grubbström (Grubba) #ifdef HAVE_IEEEFP_H
974a3f2001-08-11Henrik Grubbström (Grubba) #include <ieeefp.h> #endif /* HAVE_IEEEFP_H */
9d21f91997-01-27Fredrik Hübinette (Hubbe) #include <math.h>
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.
de91672013-06-12Henrik Grubbström (Grubba)  * * Currently they differ from the old PIKE_T variants by * TAG_FLOAT == OLD_PIKE_T_TYPE == 7
4ba6be1999-12-11Henrik Grubbström (Grubba)  * and
de91672013-06-12Henrik Grubbström (Grubba)  * TAG_TYPE == OLD_PIKE_T_FLOAT == 9 * * The old PIKE_T variants in turn differ from the current for values * less than 16 (aka MAX_TYPE) by bit 3 (mask 0x0008 (aka MIN_REF_TYPE)) * being inverted. *
4ba6be1999-12-11Henrik Grubbström (Grubba)  * These are NOT to be renumbered unless the file-format version is changed! */
f0d4682008-02-07Martin Stjernholm /* Current encoding: ¶ke0
be273a2000-09-11Henrik Grubbström (Grubba)  * * +---+-+-+-------+
de91672013-06-12Henrik Grubbström (Grubba)  * |s z|s|n| t a g |
be273a2000-09-11Henrik Grubbström (Grubba)  * +---+-+-+-------+ * sz size/small int * s small int indicator * n negative (or rather inverted)
de91672013-06-12Henrik Grubbström (Grubba)  * tag TAG_type (4 bits)
be273a2000-09-11Henrik Grubbström (Grubba)  */
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 */
8d37f12003-06-03Martin Stjernholm #define TAG_DELAYED 14 /* Note: Coincides with T_ZERO. */
4ba6be1999-12-11Henrik Grubbström (Grubba) #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))
c4c6ae2003-06-12Martin Stjernholm #define COUNTER_START (-MAX_SMALL)
4ba6be1999-12-11Henrik Grubbström (Grubba) 
9182912002-05-10Henrik Grubbström (Grubba) /* Entries used to encode the identifier_references table. */
aeed272004-05-19Henrik Grubbström (Grubba) #define ID_ENTRY_TYPE_CONSTANT -4
82723d2003-11-25Henrik Grubbström (Grubba) #define ID_ENTRY_EFUN_CONSTANT -3
9182912002-05-10Henrik Grubbström (Grubba) #define ID_ENTRY_RAW -2 #define ID_ENTRY_EOT -1 #define ID_ENTRY_VARIABLE 0 #define ID_ENTRY_FUNCTION 1 #define ID_ENTRY_CONSTANT 2 #define ID_ENTRY_INHERIT 3
62b0e92008-02-02Henrik Grubbström (Grubba) #define ID_ENTRY_ALIAS 4
9182912002-05-10Henrik Grubbström (Grubba) 
a63ecd2011-03-19Martin Stjernholm static struct object *lookup_codec (struct pike_string *codec_name) { struct object *m = get_master(); if (!m) { /* Use a dummy if there's no master around yet. This will cause an * error in apply later, so we don't need to bother. */ return clone_object (null_program, 0); } else { ref_push_object (m); ref_push_string (codec_name); o_index(); if (UNSAFE_IS_ZERO (Pike_sp - 1)) { add_ref (m); return m; } else { apply_svalue (Pike_sp - 1, 0);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) != T_OBJECT)
a63ecd2011-03-19Martin Stjernholm  Pike_error ("master()->%s() did not return an object. Got: %O\n", codec_name->str, Pike_sp - 1); m = (--Pike_sp)->u.object; pop_stack(); return m; } } }
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;
8d37f12003-06-03Martin Stjernholm  /* The encoded mapping maps encoded things to their entry IDs. A
b8a8642003-06-11Martin Stjernholm  * value less than COUNTER_START means that it's a forward reference * to a thing not yet encoded. */
8d37f12003-06-03Martin Stjernholm  struct array *delayed;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  dynamic_buffer buf;
b55a122001-07-10Martin Stjernholm #ifdef ENCODE_DEBUG int debug, depth; #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe) };
a63ecd2011-03-19Martin Stjernholm static struct object *encoder_codec (struct encode_data *data) { struct pike_string *encoder_str; if (data->codec) return data->codec; MAKE_CONST_STRING (encoder_str, "Encoder"); return data->codec = lookup_codec (encoder_str); }
9a50de2003-06-11Martin Stjernholm /* Convert to/from forward reference ID. */ #define CONVERT_ENTRY_ID(ID) (-((ID) - COUNTER_START) - (-COUNTER_START + 1))
b8a8642003-06-11Martin Stjernholm 
8a86892003-06-05Martin Stjernholm static void encode_value2(struct svalue *val, struct encode_data *data, int force_encode);
05590d1998-04-23Fredrik Hübinette (Hubbe) 
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) 
3e9b112011-01-26Arne Goedeke #if PIKE_BYTEORDER == 4321
b9a7b01999-09-18Fredrik Hübinette (Hubbe) #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)
3dd4172001-07-19Henrik Grubbström (Grubba) #define adddata2(s,l) addstr((char *)(s),(l) * sizeof((s)[0]));
3ad9861997-01-26Fredrik Hübinette (Hubbe) 
1fed332014-03-12Martin Nilsson #ifdef ENCODE_DEBUG
4ba6be1999-12-11Henrik Grubbström (Grubba) /* NOTE: Fix when type encodings change. */
de91672013-06-12Henrik Grubbström (Grubba) static int tag_to_type(int tag) { if (tag == TAG_FLOAT) return T_FLOAT; if (tag == TAG_TYPE) return T_TYPE; if (tag <= MAX_TYPE) return tag ^ MIN_REF_TYPE; return tag; }
1fed332014-03-12Martin Nilsson #endif
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;
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  EDB(5,
b55a122001-07-10Martin Stjernholm  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)  }
24b92b2008-06-11Henrik Grubbström (Grubba)  /* NB: There's only space for two bits of length info. */ for(t = 0; (size_t)t < 3; 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) {
24b92b2008-06-11Henrik Grubbström (Grubba) #if 0
be273a2000-09-11Henrik Grubbström (Grubba)  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)));
24b92b2008-06-11Henrik Grubbström (Grubba) #endif /* 0 */
be273a2000-09-11Henrik Grubbström (Grubba)  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) {
9182912002-05-10Henrik Grubbström (Grubba)  EDB(5, fprintf(stderr, "%*scode_number(%d)\n", data->depth, "", num));
f00c362000-08-10Henrik Grubbström (Grubba)  code_entry(DO_NOT_WARN(num & 15), num >> 4, data);
05590d1998-04-23Fredrik Hübinette (Hubbe) }
668a302001-02-24Henrik Grubbström (Grubba) /* NOTE: Take care to encode it exactly as the corresponing
157fc62007-03-03Henrik Grubbström (Grubba)  * type string would have been encoded (cf T_FUNCTION, T_MANY, * T_STRING, PIKE_T_NSTRING).
668a302001-02-24Henrik Grubbström (Grubba)  */ static void encode_type(struct pike_type *t, struct encode_data *data) { one_more_type: if (t->type == T_MANY) {
de91672013-06-12Henrik Grubbström (Grubba)  addchar(T_FUNCTION ^ MIN_REF_TYPE);
2479672001-03-17Henrik Grubbström (Grubba)  addchar(T_MANY);
157fc62007-03-03Henrik Grubbström (Grubba)  } else if (t->type == T_STRING) {
4e6c082007-05-02Henrik Grubbström (Grubba)  if (t->car == int_type_string) {
de91672013-06-12Henrik Grubbström (Grubba)  addchar(T_STRING ^ MIN_REF_TYPE);
157fc62007-03-03Henrik Grubbström (Grubba)  } else { /* Narrow string */ addchar(PIKE_T_NSTRING);
4e6c082007-05-02Henrik Grubbström (Grubba)  encode_type(t->car, data);
157fc62007-03-03Henrik Grubbström (Grubba)  } return;
de91672013-06-12Henrik Grubbström (Grubba)  } else if (t->type <= MAX_TYPE) { addchar(t->type ^ MIN_REF_TYPE);
418a4a2002-11-22Henrik Grubbström (Grubba)  } else {
2479672001-03-17Henrik Grubbström (Grubba)  addchar(t->type);
668a302001-02-24Henrik Grubbström (Grubba)  } switch(t->type) { default:
5aad932002-08-15Marcus Comstedt  Pike_fatal("error in type tree: %d.\n", t->type);
668a302001-02-24Henrik Grubbström (Grubba)  /*NOTREACHED*/ break;
2479672001-03-17Henrik Grubbström (Grubba) 
2f1cde2007-04-26Henrik Grubbström (Grubba)  case PIKE_T_ATTRIBUTE: /* FIXME: Strip this in compat mode. */
2479672001-03-17Henrik Grubbström (Grubba)  case PIKE_T_NAME:
418a4a2002-11-22Henrik Grubbström (Grubba)  { struct svalue sval;
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(sval, PIKE_T_STRING, 0, string, (void *)t->car);
8d37f12003-06-03Martin Stjernholm  encode_value2(&sval, data, 0);
418a4a2002-11-22Henrik Grubbström (Grubba)  }
2479672001-03-17Henrik Grubbström (Grubba)  t=t->cdr; goto one_more_type;
668a302001-02-24Henrik Grubbström (Grubba)  case T_ASSIGN:
23dd8f2003-01-07Henrik Grubbström (Grubba)  {
d2361e2003-06-30Martin Stjernholm  ptrdiff_t marker = CAR_TO_INT(t);
23dd8f2003-01-07Henrik Grubbström (Grubba)  if ((marker < 0) || (marker > 9)) { Pike_fatal("Bad assign marker: %ld\n", (long)marker); } addchar('0' + marker); t = t->cdr;
9e6f6f2001-03-18Henrik Grubbström (Grubba)  }
668a302001-02-24Henrik Grubbström (Grubba)  goto one_more_type; case T_FUNCTION: while(t->type == T_FUNCTION) { encode_type(t->car, data); t = t->cdr; } addchar(T_MANY); /* FALL_THROUGH */ case T_MANY: encode_type(t->car, data); t = t->cdr; goto one_more_type;
159fdf2007-05-09Henrik Grubbström (Grubba)  case T_SCOPE: { ptrdiff_t val = CAR_TO_INT(t); addchar(val & 0xff); }
ac57102007-05-09Henrik Grubbström (Grubba)  t = t->cdr; goto one_more_type;
668a302001-02-24Henrik Grubbström (Grubba)  case T_MAPPING: case T_OR: case T_AND: encode_type(t->car, data); t = t->cdr; goto one_more_type;
54f8ac2001-03-17Henrik Grubbström (Grubba)  case T_TYPE:
8c953a2001-03-28Henrik Grubbström (Grubba)  case T_PROGRAM:
668a302001-02-24Henrik Grubbström (Grubba)  case T_ARRAY: case T_MULTISET: case T_NOT: t = t->car; goto one_more_type; case T_INT: { ptrdiff_t val;
d2361e2003-06-30Martin Stjernholm  val = CAR_TO_INT(t);
668a302001-02-24Henrik Grubbström (Grubba)  addchar((val >> 24)&0xff); addchar((val >> 16)&0xff); addchar((val >> 8)&0xff); addchar(val & 0xff);
d2361e2003-06-30Martin Stjernholm  val = CDR_TO_INT(t);
668a302001-02-24Henrik Grubbström (Grubba)  addchar((val >> 24)&0xff); addchar((val >> 16)&0xff); addchar((val >> 8)&0xff); addchar(val & 0xff); } break; 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_MIXED: case T_ZERO: case T_VOID: case PIKE_T_UNKNOWN: break; case T_OBJECT: {
d2361e2003-06-30Martin Stjernholm  addchar(CAR_TO_INT(t));
668a302001-02-24Henrik Grubbström (Grubba)  if(t->cdr) {
5a946b2003-07-01Martin Stjernholm  ptrdiff_t id = CDR_TO_INT(t);
f8d8f42001-07-01Henrik Grubbström (Grubba)  if( id >= PROG_DYNAMIC_ID_START )
668a302001-02-24Henrik Grubbström (Grubba)  {
23dd8f2003-01-07Henrik Grubbström (Grubba)  struct program *p=id_to_program(id);
e9ce612001-03-29Per Hedbor  if(p) { ref_push_program(p); }else{ push_int(0); } } else push_int( id );
668a302001-02-24Henrik Grubbström (Grubba)  }else{ push_int(0); }
8d37f12003-06-03Martin Stjernholm  /* If it's a program that should be encoded recursively then we * must delay it. Consider: * * class A {B b;} * class B {inherit A;} * * We can't dump B when the type is encountered inside A, since * upon decode B won't have a complete A to inherit then. */ encode_value2(Pike_sp-1, data, 0);
668a302001-02-24Henrik Grubbström (Grubba)  pop_stack(); break; } } }
50817d1997-10-07Fredrik Hübinette (Hubbe) 
da652c2001-05-13Fredrik Hübinette (Hubbe) static void zap_unfinished_program(struct program *p) { int e; debug_malloc_touch(p);
997a002001-11-08Fredrik Hübinette (Hubbe)  if(p->flags & PROGRAM_FIXED) return; /* allow natural zapping */
f877222008-02-06Henrik Grubbström (Grubba)  debug_malloc_touch(p);
da652c2001-05-13Fredrik Hübinette (Hubbe)  if(p->parent) { free_program(p->parent); p->parent=0; } for(e=0;e<p->num_constants;e++) { free_svalue(& p->constants[e].sval);
1ab4ac2008-01-26Martin Stjernholm  mark_free_svalue (&p->constants[e].sval);
da652c2001-05-13Fredrik Hübinette (Hubbe)  } 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; } } } }
8a86892003-06-05Martin Stjernholm /* force_encode == 0: Maybe dump the thing later, and only a forward
8d37f12003-06-03Martin Stjernholm  * reference here (applies to programs only). *
8a86892003-06-05Martin Stjernholm  * force_encode == 1: Dump the thing now.
8d37f12003-06-03Martin Stjernholm  *
8a86892003-06-05Martin Stjernholm  * force_encode == 2: A forward reference has been encoded to this
8d37f12003-06-03Martin Stjernholm  * thing. Now it's time to dump it. */
8a86892003-06-05Martin Stjernholm static void encode_value2(struct svalue *val, struct encode_data *data, int force_encode)
50817d1997-10-07Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
50817d1997-10-07Fredrik Hübinette (Hubbe) #undef encode_value2
0a92462003-06-05Henrik Grubbström (Grubba) #define encode_value2(X,Y,Z) do { \ struct svalue *_=Pike_sp; \ struct svalue *X_ = (X); \ encode_value2_(X_,Y,Z); \ if(Pike_sp != _) { \ fprintf(stderr, "Stack error when encoding:\n"); \ print_svalue(stderr, X_); \ fprintf(stderr, "\n"); \
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*X_) == T_PROGRAM) { \
0a92462003-06-05Henrik Grubbström (Grubba)  dump_program_tables(X_->u.program, 2); \ } \ Pike_fatal("encode_value2() failed %p != %p!\n", \ Pike_sp, _); \ } \
8d37f12003-06-03Martin Stjernholm  } while(0)
50817d1997-10-07Fredrik Hübinette (Hubbe) #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe) {
8133372008-05-30Martin Stjernholm  static struct svalue dested = SVALUE_INIT (T_INT, NUMBER_DESTRUCTED, 0);
3ad9861997-01-26Fredrik Hübinette (Hubbe)  INT32 i; struct svalue *tmp;
8d37f12003-06-03Martin Stjernholm  struct svalue entry_id;
583ade2000-02-16Per Hedbor 
b55a122001-07-10Martin Stjernholm #ifdef ENCODE_DEBUG data->depth += 2; #endif
017b572011-10-28Henrik Grubbström (Grubba)  if((TYPEOF(*val) == T_OBJECT || (TYPEOF(*val) == T_FUNCTION && SUBTYPEOF(*val) != FUNCTION_BUILTIN)) &&
be273a2000-09-11Henrik Grubbström (Grubba)  !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)  {
8d37f12003-06-03Martin Stjernholm  entry_id = *tmp; /* It's always a small integer. */
b8a8642003-06-11Martin Stjernholm  if (entry_id.u.integer < COUNTER_START) entry_id.u.integer = CONVERT_ENTRY_ID (entry_id.u.integer); if (force_encode && tmp->u.integer < COUNTER_START) {
8d37f12003-06-03Martin Stjernholm  EDB(1, fprintf(stderr, "%*sEncoding delayed thing to <%d>: ", data->depth, "", entry_id.u.integer); if(data->debug == 1) {
017b572011-10-28Henrik Grubbström (Grubba)  fprintf(stderr,"TAG%d", TYPEOF(*val));
8d37f12003-06-03Martin Stjernholm  }else{ print_svalue(stderr, val);
6f7ff82001-07-12Fredrik Hübinette (Hubbe) 
8d37f12003-06-03Martin Stjernholm  } fputc('\n', stderr);); code_entry (TAG_DELAYED, entry_id.u.integer, data); tmp->u.integer = entry_id.u.integer; } else { EDB(1,fprintf(stderr, "%*sEncoding TAG_AGAIN from <%d>\n", data->depth, "", entry_id.u.integer)); code_entry(TAG_AGAIN, entry_id.u.integer, data); goto encode_done; } }else { #ifdef PIKE_DEBUG
8a86892003-06-05Martin Stjernholm  if (force_encode == 2)
8d37f12003-06-03Martin Stjernholm  Pike_fatal ("Didn't find old entry for delay encoded thing.\n"); #endif
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*val) != T_TYPE) {
8d37f12003-06-03Martin Stjernholm  entry_id = data->counter; /* It's always a small integer. */ EDB(1,fprintf(stderr, "%*sEncoding to <%d>: ", data->depth, "", entry_id.u.integer); if(data->debug == 1) {
017b572011-10-28Henrik Grubbström (Grubba)  fprintf(stderr,"TAG%d", TYPEOF(*val));
8d37f12003-06-03Martin Stjernholm  }else{
0a92462003-06-05Henrik Grubbström (Grubba)  print_svalue(stderr, val);
8d37f12003-06-03Martin Stjernholm  } fputc('\n', stderr);); mapping_insert(data->encoded, val, &entry_id); data->counter.u.integer++; }
3ad9861997-01-26Fredrik Hübinette (Hubbe)  }
583ade2000-02-16Per Hedbor 
017b572011-10-28Henrik Grubbström (Grubba)  switch(TYPEOF(*val))
3ad9861997-01-26Fredrik Hübinette (Hubbe)  {
50817d1997-10-07Fredrik Hübinette (Hubbe)  case T_INT:
802fd32003-03-29Martin Stjernholm  /* NOTE: Doesn't encode NUMBER_UNDEFINED et al. */ /* But that's a feature; NUMBER_UNDEFINED is an inherently * transient value. It would lose its usefulness otherwise. * /mast */
ebd9312003-01-26Mirar (Pontus Hagland)  #if SIZEOF_INT_TYPE > 4 { INT_TYPE i=val->u.integer; if (i != (INT32)i) {
8a45852008-02-26Henrik Grubbström (Grubba)  /* Reuse the id. */ data->counter.u.integer--; /* Make sure we don't find ourselves again below... */ map_delete(data->encoded, val); /* Encode as a bignum */
ebd9312003-01-26Mirar (Pontus Hagland)  push_int(i); convert_stack_top_to_bignum();
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1,data, 0);
ebd9312003-01-26Mirar (Pontus Hagland)  pop_stack();
8a45852008-02-26Henrik Grubbström (Grubba)  /* Restore the entry we removed above. */ mapping_insert(data->encoded, val, &entry_id);
3beae42003-06-02Martin Stjernholm  goto encode_done;
ebd9312003-01-26Mirar (Pontus Hagland)  } else code_entry(TAG_INT, i,data); } #else
4ba6be1999-12-11Henrik Grubbström (Grubba)  code_entry(TAG_INT, val->u.integer,data);
ebd9312003-01-26Mirar (Pontus Hagland) #endif
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:
cfc57e2001-02-22Henrik 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");
74dfda2001-02-24Henrik Grubbström (Grubba)  code_entry(TAG_TYPE, 0, data); /* Type encoding #0 */
c335d02001-02-24Henrik Grubbström (Grubba)  encode_type(val->u.type, data);
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  EDB(2,fprintf(stderr, "%*sEncoded type to <%d>: ",
b55a122001-07-10Martin Stjernholm  data->depth, "", data->counter.u.integer); print_svalue(stderr, val); fputc('\n', stderr););
cfc57e2001-02-22Henrik 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)  {
974a3f2001-08-11Henrik Grubbström (Grubba)  double d = val->u.float_number;
f335282001-08-08Fredrik Hübinette (Hubbe)  #define Pike_FP_SNAN -4 /* Signal Not A Number */ #define Pike_FP_QNAN -3 /* Quiet Not A Number */ #define Pike_FP_NINF -2 /* Negative infinity */ #define Pike_FP_PINF -1 /* Positive infinity */ #define Pike_FP_ZERO 0 /* Backwards compatible zero */ #define Pike_FP_NZERO 1 /* Negative Zero */
50071c2001-08-09Fredrik Hübinette (Hubbe) #define Pike_FP_PZERO 0 /* Positive zero */ #define Pike_FP_UNKNOWN -4711 /* Positive zero */
f335282001-08-08Fredrik Hübinette (Hubbe)  #ifdef HAVE_FPCLASS switch(fpclass(d)) { case FP_SNAN: code_entry(TAG_FLOAT,0,data); code_entry(TAG_FLOAT,Pike_FP_SNAN,data); break; case FP_QNAN: code_entry(TAG_FLOAT,0,data); code_entry(TAG_FLOAT,Pike_FP_QNAN,data); break; case FP_NINF: code_entry(TAG_FLOAT,0,data); code_entry(TAG_FLOAT,Pike_FP_NINF,data); break; case FP_PINF: code_entry(TAG_FLOAT,0,data); code_entry(TAG_FLOAT,Pike_FP_PINF,data); break; case FP_NZERO: code_entry(TAG_FLOAT,0,data); code_entry(TAG_FLOAT,Pike_FP_NZERO,data); break; case FP_PZERO: code_entry(TAG_FLOAT,0,data);
50071c2001-08-09Fredrik Hübinette (Hubbe)  code_entry(TAG_FLOAT,Pike_FP_ZERO,data); /* normal zero */
f335282001-08-08Fredrik Hübinette (Hubbe)  break; /* Ugly, but switch gobbles breaks -Hubbe */ default: goto encode_normal_float; } break; encode_normal_float: #else {
50071c2001-08-09Fredrik Hübinette (Hubbe)  int pike_ftype=Pike_FP_UNKNOWN;
f335282001-08-08Fredrik Hübinette (Hubbe) #ifdef HAVE_ISINF
974a3f2001-08-11Henrik Grubbström (Grubba)  if(isinf(d))
f335282001-08-08Fredrik Hübinette (Hubbe)  pike_ftype=Pike_FP_PINF; else #endif #ifdef HAVE_ISNAN
974a3f2001-08-11Henrik Grubbström (Grubba)  if(isnan(d)) {
f335282001-08-08Fredrik Hübinette (Hubbe)  pike_ftype=Pike_FP_SNAN; } else #endif #ifdef HAVE_ISZERO
974a3f2001-08-11Henrik Grubbström (Grubba)  if(iszero(d))
f335282001-08-08Fredrik Hübinette (Hubbe)  pike_ftype=Pike_FP_PZERO; else #endif #ifdef HAVE_FINITE
974a3f2001-08-11Henrik Grubbström (Grubba)  if(!finite(d))
50071c2001-08-09Fredrik Hübinette (Hubbe)  pike_ftype=Pike_FP_PINF;
f335282001-08-08Fredrik Hübinette (Hubbe) #endif ; /* Terminate any remaining else */ if( #ifdef HAVE_SIGNBIT
974a3f2001-08-11Henrik Grubbström (Grubba)  signbit(d)
f335282001-08-08Fredrik Hübinette (Hubbe) #else
974a3f2001-08-11Henrik Grubbström (Grubba)  d<0.0
f335282001-08-08Fredrik Hübinette (Hubbe) #endif ) { switch(pike_ftype) { case Pike_FP_PINF: pike_ftype=Pike_FP_NINF; break; case Pike_FP_PZERO: pike_ftype=Pike_FP_NZERO; break; } }
50071c2001-08-09Fredrik Hübinette (Hubbe)  if(pike_ftype != Pike_FP_UNKNOWN)
f335282001-08-08Fredrik Hübinette (Hubbe)  { code_entry(TAG_FLOAT,0,data); code_entry(TAG_FLOAT,pike_ftype,data); break; } } #endif
974a3f2001-08-11Henrik Grubbström (Grubba)  if(d == 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 
974a3f2001-08-11Henrik Grubbström (Grubba)  tmp = FREXP(d, &y);
be273a2000-09-11Henrik Grubbström (Grubba)  x = DO_NOT_WARN((INT64)((((INT64)1)<<(sizeof(INT64)*8 - 2))*tmp)); y -= sizeof(INT64)*8 - 2;
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  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;
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  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++)
8d37f12003-06-03Martin Stjernholm  encode_value2(ITEM(val->u.array)+i, data, 0);
50817d1997-10-07Fredrik Hübinette (Hubbe)  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. */
50ea682003-03-14Henrik Grubbström (Grubba)  /* They should be handled 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);
26bb952014-04-27Martin Nilsson  free(order);
657a002000-03-26Martin Stjernholm  }
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)  {
8d37f12003-06-03Martin Stjernholm  encode_value2(ITEM(Pike_sp[-2].u.array)+i, data, 0); /* indices */ encode_value2(ITEM(Pike_sp[-1].u.array)+i, data, 0); /* values */
50817d1997-10-07Fredrik Hübinette (Hubbe)  } pop_n_elems(2);
992e8f2008-06-27Henrik Grubbström (Grubba)  /* FIXME: What about flags? */
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
583ade2000-02-16Per Hedbor 
5b15bb2001-12-10Martin Stjernholm  case T_MULTISET: { struct multiset *l = val->u.multiset;
017b572011-10-28Henrik Grubbström (Grubba)  if (multiset_indval (l) || TYPEOF(*multiset_get_cmp_less(l)) != T_INT)
5b15bb2001-12-10Martin Stjernholm  Pike_error ("FIXME: Encoding of multisets with values and/or " "custom sort function not yet implemented.\n"); else { /* Encode valueless multisets without compare functions in a * compatible way. */ code_entry(TAG_MULTISET, multiset_sizeof (l), data); if (data->canonic) { INT32 *order; if (multiset_ind_types(l) & ~(BIT_BASIC & ~BIT_TYPE)) { multiset_fix_type_field(l); if (multiset_ind_types(l) & ~(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. */ Pike_error("Canonical encoding requires basic types in indices.\n"); } check_stack(1); push_array(multiset_indices(l)); order = get_switch_order(Pike_sp[-1].u.array); order_array(Pike_sp[-1].u.array, order);
26bb952014-04-27Martin Nilsson  free(order);
5b15bb2001-12-10Martin Stjernholm  for (i = 0; i < Pike_sp[-1].u.array->size; i++)
8d37f12003-06-03Martin Stjernholm  encode_value2(ITEM(Pike_sp[-1].u.array)+i, data, 0);
5b15bb2001-12-10Martin Stjernholm  pop_stack();
657a002000-03-26Martin Stjernholm  }
5b15bb2001-12-10Martin Stjernholm  else { struct svalue ind; union msnode *node = low_multiset_first (l->msd); for (; node; node = low_multiset_next (node))
8d37f12003-06-03Martin Stjernholm  encode_value2 (low_use_multiset_index (node, ind), data, 0);
5b15bb2001-12-10Martin Stjernholm  }
657a002000-03-26Martin Stjernholm  }
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
5b15bb2001-12-10Martin Stjernholm  }
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  case T_OBJECT: check_stack(1);
52bb181999-10-25Fredrik Hübinette (Hubbe)  /* 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
81a3162002-12-07Henrik Grubbström (Grubba)  * won't work... /Hubbe
52bb181999-10-25Fredrik Hübinette (Hubbe)  */ push_int(36); apply(val->u.object,"digits",1);
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(Pike_sp[-1]) != T_STRING)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Gmp.mpz->digits did not return a string!\n");
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1, data, 0);
52bb181999-10-25Fredrik Hübinette (Hubbe)  pop_stack(); break; }
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");
8fb4b62003-06-05Martin Stjernholm  push_svalue(val);
a63ecd2011-03-19Martin Stjernholm  apply(encoder_codec (data), "nameof", 1);
295a152002-02-13Henrik Grubbström (Grubba)  EDB(5, fprintf(stderr, "%*s->nameof: ", data->depth, ""); print_svalue(stderr, Pike_sp-1); fputc('\n', stderr););
017b572011-10-28Henrik Grubbström (Grubba)  switch(TYPEOF(Pike_sp[-1]))
50817d1997-10-07Fredrik Hübinette (Hubbe)  { case T_INT:
017b572011-10-28Henrik Grubbström (Grubba)  if(SUBTYPEOF(Pike_sp[-1]) == NUMBER_UNDEFINED)
50817d1997-10-07Fredrik Hübinette (Hubbe)  {
fc2b3e2001-07-12Fredrik Hübinette (Hubbe)  int to_change = data->buf.s.len;
8d37f12003-06-03Martin Stjernholm  struct svalue tmp = entry_id;
583ade2000-02-16Per Hedbor 
295a152002-02-13Henrik Grubbström (Grubba)  EDB(5,fprintf(stderr, "%*s(UNDEFINED)\n", data->depth, ""));
017b572011-10-28Henrik Grubbström (Grubba)  if (SUBTYPEOF(*val)) {
ca12fa2008-05-28Henrik Grubbström (Grubba)  /* Subtyped object. * * Encode the subtype, and then try encoding the plain object. */ code_entry(TAG_OBJECT, 4, data);
017b572011-10-28Henrik Grubbström (Grubba)  code_number(SUBTYPEOF(*val), data);
ca12fa2008-05-28Henrik Grubbström (Grubba)  pop_stack(); ref_push_object(val->u.object); break;
c2df122004-12-18Henrik Grubbström (Grubba)  }
fc2b3e2001-07-12Fredrik Hübinette (Hubbe)  /* We have to remove ourself from the cache */ map_delete(data->encoded, val);
3b8c9b2001-07-15Fredrik Hübinette (Hubbe)  pop_stack(); push_svalue(val); f_object_program(1);
fc2b3e2001-07-12Fredrik Hübinette (Hubbe)  /* Code the program */ code_entry(TAG_OBJECT, 3,data);
8a86892003-06-05Martin Stjernholm  encode_value2(Pike_sp-1, data, 1);
fc2b3e2001-07-12Fredrik Hübinette (Hubbe)  pop_stack(); push_svalue(val);
583ade2000-02-16Per Hedbor 
fc2b3e2001-07-12Fredrik Hübinette (Hubbe)  /* If we do not exist in cache, use backwards- * compatible method, otherwise use newfangled * style=3. -Hubbe */ if(!low_mapping_lookup(data->encoded, val))
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  {
3d2ae42002-05-02Martin Stjernholm  int fun;
3b8c9b2001-07-15Fredrik Hübinette (Hubbe)  EDB(1,fprintf(stderr, "%*sZapping 3 -> 1 in TAG_OBJECT\n", data->depth, ""));
fc2b3e2001-07-12Fredrik Hübinette (Hubbe)  /* This causes the code_entry above to * become: code_entry(TAG_OBJECT, 1, data); * -Hubbe */ data->buf.s.str[to_change] = 99;
3b8c9b2001-07-15Fredrik Hübinette (Hubbe) 
a63ecd2011-03-19Martin Stjernholm  fun = find_identifier("encode_object", encoder_codec (data)->prog);
3d2ae42002-05-02Martin Stjernholm  if (fun < 0) Pike_error("Cannot encode objects without an " "\"encode_object\" function in the codec.\n"); apply_low(data->codec,fun,1);
295a152002-02-13Henrik Grubbström (Grubba) 
3b8c9b2001-07-15Fredrik Hübinette (Hubbe)  /* Put value back in cache for future reference -Hubbe */ mapping_insert(data->encoded, val, &tmp);
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  }
50817d1997-10-07Fredrik Hübinette (Hubbe)  break; } /* FALL THROUGH */
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  default:
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  code_entry(TAG_OBJECT, 0,data);
50817d1997-10-07Fredrik Hübinette (Hubbe)  break; }
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1, data, 0);
50817d1997-10-07Fredrik Hübinette (Hubbe)  pop_stack(); break;
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  case T_FUNCTION:
3520112001-08-10Martin Stjernholm  /* FIXME: Ought to have special treatment of trampolines. */
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);
8fb4b62003-06-05Martin Stjernholm  push_svalue(val);
a63ecd2011-03-19Martin Stjernholm  apply(encoder_codec (data),"nameof", 1);
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(Pike_sp[-1]) == T_INT && SUBTYPEOF(Pike_sp[-1]) == NUMBER_UNDEFINED)
50817d1997-10-07Fredrik Hübinette (Hubbe)  {
017b572011-10-28Henrik Grubbström (Grubba)  if(SUBTYPEOF(*val) != FUNCTION_BUILTIN)
50817d1997-10-07Fredrik Hübinette (Hubbe)  {
38979d2004-12-20Martin Stjernholm  if(really_low_find_shared_string_identifier(
017b572011-10-28Henrik Grubbström (Grubba)  ID_FROM_INT(val->u.object->prog, SUBTYPEOF(*val))->name,
38979d2004-12-20Martin Stjernholm  val->u.object->prog,
017b572011-10-28Henrik Grubbström (Grubba)  SEE_PROTECTED|SEE_PRIVATE) == SUBTYPEOF(*val))
17c2662001-07-03Fredrik Hübinette (Hubbe)  {
50817d1997-10-07Fredrik Hübinette (Hubbe)  /* We have to remove ourself from the cache for now */
8d37f12003-06-03Martin Stjernholm  struct svalue tmp = entry_id;
50817d1997-10-07Fredrik Hübinette (Hubbe)  map_delete(data->encoded, val);
583ade2000-02-16Per Hedbor 
974a3f2001-08-11Henrik Grubbström (Grubba)  code_entry(TAG_FUNCTION, 1, data);
017b572011-10-28Henrik Grubbström (Grubba)  ref_push_object(val->u.object);
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1, data, 0);
017b572011-10-28Henrik Grubbström (Grubba)  ref_push_string(ID_FROM_INT(val->u.object->prog, SUBTYPEOF(*val))->name);
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1, data, 0);
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);
3beae42003-06-02Martin Stjernholm  goto encode_done;
17c2662001-07-03Fredrik Hübinette (Hubbe)  }
38979d2004-12-20Martin Stjernholm  else { /* FIXME: Encode the object, the inherit and the name. */ Pike_error("Cannot encode overloaded functions (yet).\n"); }
50817d1997-10-07Fredrik Hübinette (Hubbe)  }
3beae42003-06-02Martin Stjernholm  Pike_error("Cannot encode builtin functions.\n");
50817d1997-10-07Fredrik Hübinette (Hubbe)  }
3ad9861997-01-26Fredrik Hübinette (Hubbe) 
974a3f2001-08-11Henrik Grubbström (Grubba)  code_entry(TAG_FUNCTION, 0, data);
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1, data, 0);
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;
f8d8f42001-07-01Henrik Grubbström (Grubba)  if (val->u.program->id < PROG_DYNAMIC_ID_START) {
974a3f2001-08-11Henrik Grubbström (Grubba)  code_entry(TAG_PROGRAM, 3, data);
f8d8f42001-07-01Henrik Grubbström (Grubba)  push_int(val->u.program->id);
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1, data, 0);
f8d8f42001-07-01Henrik Grubbström (Grubba)  pop_stack(); break; }
657a002000-03-26Martin Stjernholm  if (data->canonic)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Canonical encoding of programs not supported.\n");
76a9bd2007-01-05Henrik Grubbström (Grubba)  if (!(val->u.program->flags & PROGRAM_FIXED)) Pike_error("Encoding of unfixated programs not supported.\n");
50817d1997-10-07Fredrik Hübinette (Hubbe)  check_stack(1);
8fb4b62003-06-05Martin Stjernholm  push_svalue(val);
a63ecd2011-03-19Martin Stjernholm  apply(encoder_codec (data),"nameof", 1);
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(Pike_sp[-1]) == TYPEOF(*val))
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Error in master()->nameof(), same type returned.\n");
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(Pike_sp[-1]) == T_INT && SUBTYPEOF(Pike_sp[-1]) == NUMBER_UNDEFINED)
05590d1998-04-23Fredrik Hübinette (Hubbe)  { struct program *p=val->u.program;
f877222008-02-06Henrik Grubbström (Grubba)  debug_malloc_touch(p);
8d37f12003-06-03Martin Stjernholm  pop_stack();
51717a2001-04-09Fredrik Hübinette (Hubbe)  if( (p->flags & PROGRAM_HAS_C_METHODS) || p->event_handler ) {
0a8db82013-11-07Henrik Grubbström (Grubba)  int has_local_c_methods = 0; for (d = 0; d < p->num_identifiers; d++) { if (IDENTIFIER_IS_C_FUNCTION(p->identifiers[d].identifier_flags)) { has_local_c_methods = 1; break; } } if (has_local_c_methods) { if(p->parent) { /* We have to remove ourselves from the cache for now */ struct svalue tmp = entry_id; EDB(1, fprintf(stderr, "%*sencode: encoding C program via parent.\n", data->depth, "")); map_delete(data->encoded, val); code_entry(TAG_PROGRAM, 2, data); ref_push_program(p->parent); encode_value2(Pike_sp-1, data, 0);
51717a2001-04-09Fredrik Hübinette (Hubbe) 
0a8db82013-11-07Henrik Grubbström (Grubba)  ref_push_program(p); f_function_name(1);
272fe82013-06-16Henrik Grubbström (Grubba) #if 0
0a8db82013-11-07Henrik Grubbström (Grubba)  if(TYPEOF(Pike_sp[-1]) == PIKE_T_INT) Pike_error("Cannot encode C programs.\n");
272fe82013-06-16Henrik Grubbström (Grubba) #endif
0a8db82013-11-07Henrik Grubbström (Grubba)  encode_value2(Pike_sp-1, data, 0);
51717a2001-04-09Fredrik Hübinette (Hubbe) 
0a8db82013-11-07Henrik Grubbström (Grubba)  pop_n_elems(2);
51717a2001-04-09Fredrik Hübinette (Hubbe) 
0a8db82013-11-07Henrik Grubbström (Grubba)  /* Put value back in cache */ mapping_insert(data->encoded, val, &tmp); goto encode_done; } if( p->event_handler ) Pike_error("Cannot encode programs with event handlers.\n");
272fe82013-06-16Henrik Grubbström (Grubba) #if 0
0a8db82013-11-07Henrik Grubbström (Grubba)  Pike_error("Cannot encode C programs.\n");
272fe82013-06-16Henrik Grubbström (Grubba) #endif
0a8db82013-11-07Henrik Grubbström (Grubba)  } else { EDB(1, fprintf(stderr, "%*sencode: encoding program overloading a C program.\n", data->depth, "")); }
51717a2001-04-09Fredrik Hübinette (Hubbe)  }
9182912002-05-10Henrik Grubbström (Grubba) 
8d37f12003-06-03Martin Stjernholm #ifdef OLD_PIKE_ENCODE_PROGRAM
9182912002-05-10Henrik Grubbström (Grubba)  EDB(1,
8d37f12003-06-03Martin Stjernholm  fprintf(stderr, "%*sencode: encoding program in old style\n",
9182912002-05-10Henrik Grubbström (Grubba)  data->depth, "")); /* Type 1 -- Old-style encoding. */
974a3f2001-08-11Henrik Grubbström (Grubba)  code_entry(TAG_PROGRAM, 1, data);
091b322005-05-27Martin Stjernholm  push_compact_version();
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1,data, 0);
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);
9182912002-05-10Henrik Grubbström (Grubba)  code_number(p->xstorage,data); /**/ code_number(p->parent_info_storage,data); /**/
f3c7152001-04-14Fredrik Hübinette (Hubbe) 
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);
f3c7152001-04-14Fredrik Hübinette (Hubbe)  if(p->parent) ref_push_program(p->parent); else push_int(0);
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1,data, 0); /**/
f3c7152001-04-14Fredrik Hübinette (Hubbe)  pop_stack();
7e877a2003-04-02Martin Stjernholm #define FOO(NUMTYPE,TYPE,ARGTYPE,NAME) \ code_number( p->PIKE_CONCAT(num_,NAME), data);
05590d1998-04-23Fredrik Hübinette (Hubbe) #include "program_areas.h"
869aed2001-07-23Henrik Grubbström (Grubba)  code_number(PIKE_BYTECODE_METHOD, data);
697e0a2001-07-20Henrik Grubbström (Grubba) #ifdef ENCODE_PROGRAM
21394f2001-07-22Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG {
258c8e2001-07-23Henrik Grubbström (Grubba)  ptrdiff_t bufpos = data->buf.s.len;
21394f2001-07-22Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */ ENCODE_PROGRAM(p, &(data->buf)); #ifdef PIKE_DEBUG if (p->num_program * sizeof(p->program[0]) !=
258c8e2001-07-23Henrik Grubbström (Grubba)  data->buf.s.len - bufpos) {
5aad932002-08-15Marcus Comstedt  Pike_fatal("ENCODE_PROGRAM() failed:\n"
21394f2001-07-22Henrik Grubbström (Grubba)  "Encoded data len: %ld\n" "Expected data len: %ld\n", DO_NOT_WARN((long)(p->num_program * sizeof(p->program[0]))),
258c8e2001-07-23Henrik Grubbström (Grubba)  DO_NOT_WARN((long)(data->buf.s.len - bufpos)));
21394f2001-07-22Henrik Grubbström (Grubba)  } } #endif /* PIKE_DEBUG */
697e0a2001-07-20Henrik Grubbström (Grubba) #else /* !ENCODE_PROGRAM */
05590d1998-04-23Fredrik Hübinette (Hubbe)  adddata2(p->program, p->num_program);
697e0a2001-07-20Henrik Grubbström (Grubba) #endif /* ENCODE_PROGRAM */
9182912002-05-10Henrik Grubbström (Grubba) 
3dd4172001-07-19Henrik Grubbström (Grubba)  adddata2(p->relocations, p->num_relocations);
05590d1998-04-23Fredrik Hübinette (Hubbe)  adddata2(p->linenumbers, p->num_linenumbers);
f3c7152001-04-14Fredrik Hübinette (Hubbe) 
05590d1998-04-23Fredrik Hübinette (Hubbe)  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);
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  EDB(3,fprintf(stderr,"IDREF%x > %d: { %d, %d, %d }\n",
17c2662001-07-03Fredrik Hübinette (Hubbe)  p->id,d, p->identifier_references[d].inherit_offset, p->identifier_references[d].identifier_offset,
b55a122001-07-10Martin Stjernholm  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) {
c07fe52003-01-16Martin Stjernholm  ref_push_function(p->inherits[d].parent, p->inherits[d].parent_identifier);
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  EDB(3,fprintf(stderr,"INHERIT%x coded as func { %p, %d }\n",
24b92b2008-06-11Henrik Grubbström (Grubba)  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{
a72ad72001-07-03Henrik Grubbström (Grubba)  Pike_error("Failed to encode inherit #%d\n", d);
05590d1998-04-23Fredrik Hübinette (Hubbe)  push_int(0); }
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1,data, 1);
05590d1998-04-23Fredrik Hübinette (Hubbe)  pop_stack();
11b69f1999-09-17Fredrik Hübinette (Hubbe)  adddata3(p->inherits[d].name);
17c2662001-07-03Fredrik Hübinette (Hubbe) 
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  EDB(3,fprintf(stderr,"INHERIT%x > %d: %d id=%d\n",
17c2662001-07-03Fredrik Hübinette (Hubbe)  p->id,d, p->inherits[d].prog->num_identifiers,
b55a122001-07-10Martin Stjernholm  p->inherits[d].prog->id););
05590d1998-04-23Fredrik Hübinette (Hubbe)  } for(d=0;d<p->num_identifiers;d++) { adddata(p->identifiers[d].name);
c335d02001-02-24Henrik Grubbström (Grubba)  encode_type(p->identifiers[d].type, data);
05590d1998-04-23Fredrik Hübinette (Hubbe)  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);
865d652008-05-16Henrik Grubbström (Grubba)  code_number(p->identifiers[d].filename_strno, data); code_number(p->identifiers[d].linenumber, data);
e6dd052007-10-03Henrik Grubbström (Grubba)  if (IDENTIFIER_IS_ALIAS(p->identifiers[d].identifier_flags)) { code_number(p->identifiers[d].func.ext_ref.depth,data); code_number(p->identifiers[d].func.ext_ref.id,data); } else if (!IDENTIFIER_IS_C_FUNCTION(p->identifiers[d].identifier_flags)) {
a72ad72001-07-03Henrik Grubbström (Grubba)  code_number(p->identifiers[d].func.offset,data); } else { Pike_error("Cannot encode functions implemented in C "
9606eb2004-11-12Henrik Grubbström (Grubba)  "(identifier=\"%S\").\n", p->identifiers[d].name);
a72ad72001-07-03Henrik Grubbström (Grubba)  }
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  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)  {
8d37f12003-06-03Martin Stjernholm  encode_value2(& p->constants[d].sval, data, 0);
4ea54f2004-05-29Henrik Grubbström (Grubba)  adddata3(NULL /* p->constants[d].name */);
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  }
9182912002-05-10Henrik Grubbström (Grubba)  #else /* !OLD_PIKE_ENCODE_PROGRAM */
8d37f12003-06-03Martin Stjernholm  /* Portable encoding (4 and 5). */
8a86892003-06-05Martin Stjernholm  if (!force_encode) {
8d37f12003-06-03Martin Stjernholm  /* Encode later (5). */ EDB(1, fprintf(stderr, "%*sencode: delayed encoding of program\n", data->depth, "")); code_entry (TAG_PROGRAM, 5, data); data->delayed = append_array (data->delayed, val); tmp = low_mapping_lookup (data->encoded, val);
77a8912008-01-16Henrik Grubbström (Grubba)  if (!tmp) Pike_error("Internal error in delayed encoder of programs.\n");
b8a8642003-06-11Martin Stjernholm  tmp->u.integer = CONVERT_ENTRY_ID (tmp->u.integer);
8d37f12003-06-03Martin Stjernholm  goto encode_done; } EDB(1, fprintf(stderr, "%*sencode: encoding program in new style\n", data->depth, "")); code_entry(TAG_PROGRAM, 4, data);
9182912002-05-10Henrik Grubbström (Grubba)  /* Byte-order. */ code_number(PIKE_BYTEORDER, data); /* flags */ code_number(p->flags,data); /* version */
091b322005-05-27Martin Stjernholm  push_compact_version();
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1, data, 0);
9182912002-05-10Henrik Grubbström (Grubba)  pop_stack(); /* parent */ if (p->parent) { ref_push_program(p->parent); } else { push_int(0); }
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1, data, 0);
9182912002-05-10Henrik Grubbström (Grubba)  pop_stack(); /* num_* */
7e877a2003-04-02Martin Stjernholm #define FOO(NUMTYPE,TYPE,ARGTYPE,NAME) \ code_number( p->PIKE_CONCAT(num_,NAME), data);
9182912002-05-10Henrik Grubbström (Grubba) #include "program_areas.h" /* Byte-code method */
82723d2003-11-25Henrik Grubbström (Grubba) #ifdef PIKE_PORTABLE_BYTECODE code_number(PIKE_BYTECODE_PORTABLE, data); #else /* !PIKE_PORTABLE_BYTECODE */
9182912002-05-10Henrik Grubbström (Grubba)  code_number(PIKE_BYTECODE_METHOD, data);
6b06d82003-11-17Henrik Grubbström (Grubba) #ifdef PIKE_USE_MACHINE_CODE /* Add the checksum of the instrs array. */ code_number(instrs_checksum, data); #endif /* PIKE_USE_MACHINE_CODE */
9182912002-05-10Henrik Grubbström (Grubba)  /* program */ #ifdef ENCODE_PROGRAM #ifdef PIKE_DEBUG { ptrdiff_t bufpos = data->buf.s.len; #endif /* PIKE_DEBUG */ ENCODE_PROGRAM(p, &(data->buf)); #ifdef PIKE_DEBUG if (p->num_program * sizeof(p->program[0]) != data->buf.s.len - bufpos) {
5aad932002-08-15Marcus Comstedt  Pike_fatal("ENCODE_PROGRAM() failed:\n"
9182912002-05-10Henrik Grubbström (Grubba)  "Encoded data len: %ld\n" "Expected data len: %ld\n", DO_NOT_WARN((long)(p->num_program * sizeof(p->program[0]))), DO_NOT_WARN((long)(data->buf.s.len - bufpos))); } } #endif /* PIKE_DEBUG */ #else /* !ENCODE_PROGRAM */ adddata2(p->program, p->num_program); #endif /* ENCODE_PROGRAM */ /* relocations */ for(d=0; d<(int)p->num_relocations; d++) { code_number(p->relocations[d], data); } /* linenumbers */ adddata2(p->linenumbers, p->num_linenumbers);
82723d2003-11-25Henrik Grubbström (Grubba) #endif /* PIKE_PORTABLE_BYTECODE */
9182912002-05-10Henrik Grubbström (Grubba)  { struct svalue str_sval;
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(str_sval, T_STRING, 0, string, NULL);
9182912002-05-10Henrik Grubbström (Grubba)  /* strings */ for(d=0;d<p->num_strings;d++) { str_sval.u.string = p->strings[d];
8d37f12003-06-03Martin Stjernholm  encode_value2(&str_sval, data, 0);
9182912002-05-10Henrik Grubbström (Grubba)  } } EDB(5, dump_program_tables(p, data->depth));
82723d2003-11-25Henrik Grubbström (Grubba) #ifdef PIKE_PORTABLE_BYTECODE /* Encode the efun constants since they are needed by the optimizer. */ { struct svalue str_sval;
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(str_sval, T_STRING, 0, string, NULL);
82723d2003-11-25Henrik Grubbström (Grubba)  /* constants */ for(d=0;d<p->num_constants;d++) {
017b572011-10-28Henrik Grubbström (Grubba)  if ((TYPEOF(p->constants[d].sval) == T_FUNCTION) && (SUBTYPEOF(p->constants[d].sval) == FUNCTION_BUILTIN)) {
aeed272004-05-19Henrik Grubbström (Grubba)  code_number(ID_ENTRY_EFUN_CONSTANT, data);
017b572011-10-28Henrik Grubbström (Grubba)  } else if (TYPEOF(p->constants[d].sval) == T_TYPE) {
aeed272004-05-19Henrik Grubbström (Grubba)  code_number(ID_ENTRY_TYPE_CONSTANT, data); } else {
82723d2003-11-25Henrik Grubbström (Grubba)  continue; } code_number(d, data); /* value */ encode_value2(&p->constants[d].sval, data, 0); /* name */
4ea54f2004-05-29Henrik Grubbström (Grubba) #if 0
82723d2003-11-25Henrik Grubbström (Grubba)  if (p->constants[d].name) { str_sval.u.string = p->constants[d].name; encode_value2(&str_sval, data, 0); } else {
4ea54f2004-05-29Henrik Grubbström (Grubba) #endif /* 0 */
82723d2003-11-25Henrik Grubbström (Grubba)  push_int(0); encode_value2(Pike_sp-1, data, 0); dmalloc_touch_svalue(Pike_sp-1); Pike_sp--;
4ea54f2004-05-29Henrik Grubbström (Grubba) #if 0
82723d2003-11-25Henrik Grubbström (Grubba)  }
4ea54f2004-05-29Henrik Grubbström (Grubba) #endif /* 0 */
82723d2003-11-25Henrik Grubbström (Grubba)  } } #endif /* PIKE_PORTABLE_BYTECODE */
9182912002-05-10Henrik Grubbström (Grubba)  /* Dump the identifiers in a portable manner... */ { int inherit_num = 1; struct svalue str_sval;
b81a1d2014-04-27Martin Nilsson  char *id_dumped = alloca(p->num_identifiers);
49a3442009-08-19Henrik Grubbström (Grubba)  int d_min = 0;
9182912002-05-10Henrik Grubbström (Grubba)  MEMSET(id_dumped,0,p->num_identifiers);
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(str_sval, T_STRING, 0, string, NULL);
9182912002-05-10Henrik Grubbström (Grubba)  EDB(2, fprintf(stderr, "%*sencode: encoding references\n", data->depth, "")); #ifdef ENCODE_DEBUG data->depth += 2; #endif /* NOTE: d is incremented by hand inside the loop. */ for (d=0; d < p->num_identifier_references;) { int d_max = p->num_identifier_references; /* Find insertion point of next inherit. */ if (inherit_num < p->num_inherits) { d_max = p->inherits[inherit_num].identifier_ref_offset; }
8d37f12003-06-03Martin Stjernholm  EDB (4, fprintf (stderr, "%*sencode: inherit_num: %d, d_max: %d\n", data->depth, "", inherit_num, d_max););
9182912002-05-10Henrik Grubbström (Grubba)  /* Fix locally defined identifiers. */ for (; d < d_max; d++) { struct reference *ref = p->identifier_references + d; struct inherit *inh = INHERIT_FROM_PTR(p, ref); struct identifier *id = ID_FROM_PTR(p, ref); /* Skip identifiers that haven't been overloaded. */
272fe82013-06-16Henrik Grubbström (Grubba)  if (ref->id_flags & ID_INHERITED) { if ((ref->id_flags & (ID_VARIANT|ID_HIDDEN)) == ID_VARIANT) { /* Find the dispatcher. */ int i = really_low_find_shared_string_identifier(id->name, p, SEE_PROTECTED|SEE_PRIVATE); /* NB: We use the id_dumped flag for the * dispatcher to mark whether we have * dumped the first variant of this * name in this program. */ if ((i >= 0) && !is_variant_dispatcher(p, i) && !PTR_FROM_INT(p, i)->inherit_offset) { /* Overloaded in this program. * * Make sure later variants don't clear this one. */ id_dumped[PTR_FROM_INT(p, i)->identifier_offset] = 1; } } continue; }
9182912002-05-10Henrik Grubbström (Grubba) 
2704c22006-10-27Henrik Grubbström (Grubba)  /* Skip getter/setter variables; they get pulled in * by their respective functions. */
e6dd052007-10-03Henrik Grubbström (Grubba)  if (!IDENTIFIER_IS_ALIAS(id->identifier_flags) && IDENTIFIER_IS_VARIABLE(id->identifier_flags) &&
2704c22006-10-27Henrik Grubbström (Grubba)  (id->run_time_type == PIKE_T_GET_SET)) continue;
9182912002-05-10Henrik Grubbström (Grubba)  EDB(3, fprintf(stderr, "%*sencoding identifier ref %d: %4x \"%s\"\n", data->depth, "", d, id->identifier_flags, id->name->str)); #ifdef ENCODE_DEBUG data->depth += 2; #endif /* Variable, constant or function. */ if (ref->inherit_offset || ref->id_flags & ID_HIDDEN) { int ref_no = -1; /* Explicit reference to inherited symbol. */ EDB(3, fprintf(stderr, "%*sencode: encoding raw reference\n", data->depth, "")); code_number(ID_ENTRY_RAW, data); code_number(ref->id_flags, data); /* inherit_offset */ code_number(ref->inherit_offset, data); /* identifier_offset */ /* Find the corresponding identifier reference * in the inherit. */ { struct program *p2 = p->inherits[ref->inherit_offset].prog;
dc672b2008-02-08Henrik Grubbström (Grubba)  int i;
f877222008-02-06Henrik Grubbström (Grubba)  debug_malloc_touch(p); debug_malloc_touch(p2);
9182912002-05-10Henrik Grubbström (Grubba)  for (i=0; i < p2->num_identifier_references; i++) { struct reference *ref2 = p2->identifier_references + i; if (!(ref2->inherit_offset) && !(ref2->id_flags & ID_HIDDEN) && (ref2->identifier_offset == ref->identifier_offset)) { ref_no = i; break; } } } if (ref_no == -1) { Pike_error("Failed to reverse explicit reference\n"); } code_number(ref_no, data); } else {
2704c22006-10-27Henrik Grubbström (Grubba)  int gs_flags = -1;
9182912002-05-10Henrik Grubbström (Grubba)  if (id_dumped[ref->identifier_offset]) { EDB(3, fprintf(stderr, "%*sencode: already encoded reference\n", data->depth, "")); goto next_identifier_ref; } id_dumped[ref->identifier_offset] = 1;
2704c22006-10-27Henrik Grubbström (Grubba)  if (id->name && (id->name->len>3) && (index_shared_string(id->name, 0) == '`') && (index_shared_string(id->name, 1) == '-') && (index_shared_string(id->name, 2) == '>')) {
865d652008-05-16Henrik Grubbström (Grubba)  /* Potential old-style getter/setter. */
2704c22006-10-27Henrik Grubbström (Grubba)  struct pike_string *symbol = NULL; if (index_shared_string(id->name, id->name->len-1) != '=') { /* Getter callback. */ symbol = string_slice(id->name, 3, id->name->len - 3); } else if (id->name->len > 4) { /* Setter callback. */ symbol = string_slice(id->name, 3, id->name->len - 4); } if (symbol) { int i = really_low_find_shared_string_identifier(symbol, p,
6530932008-06-29Martin Nilsson  SEE_PROTECTED|SEE_PRIVATE);
2704c22006-10-27Henrik Grubbström (Grubba)  if (i >= 0) { /* Found the symbol. */ gs_flags = PTR_FROM_INT(p, i)->id_flags; } free_string(symbol); }
865d652008-05-16Henrik Grubbström (Grubba)  } else if (id->name && (id->name->len>1) && (index_shared_string(id->name, 0) == '`') && ((((unsigned)index_shared_string(id->name, 1)) >= 256) || isidchar(index_shared_string(id->name, 1)))) { /* New-style getter/setter. */ struct pike_string *symbol = NULL; if (index_shared_string(id->name, id->name->len-1) != '=') { /* Getter callback. */ symbol = string_slice(id->name, 1, id->name->len - 1); } else if (id->name->len > 2) { /* Setter callback. */ symbol = string_slice(id->name, 1, id->name->len - 2); } if (symbol) { int i = really_low_find_shared_string_identifier(symbol, p,
6530932008-06-29Martin Nilsson  SEE_PROTECTED|SEE_PRIVATE);
865d652008-05-16Henrik Grubbström (Grubba)  if (i >= 0) { /* Found the symbol. */ gs_flags = PTR_FROM_INT(p, i)->id_flags; } free_string(symbol); }
272fe82013-06-16Henrik Grubbström (Grubba)  } else if (ref->id_flags & ID_VARIANT) { /* Find the dispatcher. */ int i = really_low_find_shared_string_identifier(id->name, p, SEE_PROTECTED|SEE_PRIVATE); /* NB: We use the id_dumped flag for the * dispatcher to mark whether we have * dumped the first variant of this * name in this program. */ if ((i < 0) || !is_variant_dispatcher(p, i)) { Pike_error("Failed to find dispatcher for inherited " "variant function: %S\n", id->name); } if (PTR_FROM_INT(p, i)->inherit_offset) { Pike_error("Dispatcher for variant function %S " "is inherited.\n", id->name); } gs_flags = ref->id_flags & PTR_FROM_INT(p, i)->id_flags; if (id_dumped[PTR_FROM_INT(p, i)->identifier_offset]) { gs_flags |= ID_VARIANT; } else { /* First variant. */ id_dumped[PTR_FROM_INT(p, i)->identifier_offset] = 1; }
2704c22006-10-27Henrik Grubbström (Grubba)  }
e6dd052007-10-03Henrik Grubbström (Grubba)  if (IDENTIFIER_IS_ALIAS(id->identifier_flags)) {
aafd5d2008-02-14Henrik Grubbström (Grubba)  if ((!id->func.ext_ref.depth) && IDENTIFIER_IS_VARIABLE(id->identifier_flags)) {
ca553a2008-02-14Henrik Grubbström (Grubba)  struct identifier *other = ID_FROM_INT(p, id->func.ext_ref.id); if (other->name == id->name) { /* Let define_variable() handle the decoding. */ EDB(3, fprintf(stderr, "%*sencode: encoding aliased variable\n", data->depth, "")); goto encode_entry_variable; }
aafd5d2008-02-14Henrik Grubbström (Grubba)  } EDB(3, fprintf(stderr, "%*sencode: encoding alias\n", data->depth, ""));
62b0e92008-02-02Henrik Grubbström (Grubba)  code_number(ID_ENTRY_ALIAS, data); /* flags */ code_number(ref->id_flags, data); /* name */ str_sval.u.string = id->name; encode_value2(&str_sval, data, 0);
865d652008-05-16Henrik Grubbström (Grubba)  /* type */ ref_push_type_value(id->type); encode_value2(Pike_sp-1, data, 0); pop_stack(); /* filename */ code_number(id->filename_strno, data); /* linenumber */ code_number(id->linenumber, data);
62b0e92008-02-02Henrik Grubbström (Grubba)  /* depth */ code_number(id->func.ext_ref.depth, data); /* refno */ code_number(id->func.ext_ref.id, data);
e6dd052007-10-03Henrik Grubbström (Grubba)  } else switch (id->identifier_flags & IDENTIFIER_TYPE_MASK) {
53ccc82003-08-03Martin Stjernholm  case IDENTIFIER_CONSTANT:
9182912002-05-10Henrik Grubbström (Grubba)  EDB(3, fprintf(stderr, "%*sencode: encoding constant\n", data->depth, "")); code_number(ID_ENTRY_CONSTANT, data);
2704c22006-10-27Henrik Grubbström (Grubba)  if (gs_flags >= 0) { code_number(gs_flags, data); } else { code_number(ref->id_flags, data); }
9182912002-05-10Henrik Grubbström (Grubba)  /* name */ str_sval.u.string = id->name;
8d37f12003-06-03Martin Stjernholm  encode_value2(&str_sval, data, 0);
9182912002-05-10Henrik Grubbström (Grubba)  /* type */ ref_push_type_value(id->type);
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1, data, 0);
9182912002-05-10Henrik Grubbström (Grubba)  pop_stack();
865d652008-05-16Henrik Grubbström (Grubba)  /* filename */ code_number(id->filename_strno, data); /* linenumber */ code_number(id->linenumber, data); /* offset */
89378b2010-11-23Henrik Grubbström (Grubba)  code_number(id->func.const_info.offset, data);
865d652008-05-16Henrik Grubbström (Grubba) 
9182912002-05-10Henrik Grubbström (Grubba)  /* run-time type */ code_number(id->run_time_type, data);
0e248f2009-08-09Henrik Grubbström (Grubba)  /* opt flags */ code_number(id->opt_flags, data);
53ccc82003-08-03Martin Stjernholm  break;
9182912002-05-10Henrik Grubbström (Grubba) 
53ccc82003-08-03Martin Stjernholm  case IDENTIFIER_PIKE_FUNCTION:
9182912002-05-10Henrik Grubbström (Grubba)  EDB(3, fprintf(stderr, "%*sencode: encoding function\n", data->depth, "")); code_number(ID_ENTRY_FUNCTION, data);
2704c22006-10-27Henrik Grubbström (Grubba)  if (gs_flags >= 0) { code_number(gs_flags, data); } else { code_number(ref->id_flags, data); }
9182912002-05-10Henrik Grubbström (Grubba)  /* name */ str_sval.u.string = id->name;
8d37f12003-06-03Martin Stjernholm  encode_value2(&str_sval, data, 0);
9182912002-05-10Henrik Grubbström (Grubba)  /* type */ ref_push_type_value(id->type);
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1, data, 0);
9182912002-05-10Henrik Grubbström (Grubba)  pop_stack();
865d652008-05-16Henrik Grubbström (Grubba)  /* filename */ code_number(id->filename_strno, data); /* linenumber */ code_number(id->linenumber, data);
9182912002-05-10Henrik Grubbström (Grubba)  /* func_flags (aka identifier_flags) */ code_number(id->identifier_flags, data); /* func */
82723d2003-11-25Henrik Grubbström (Grubba) #ifdef PIKE_PORTABLE_BYTECODE if (id->func.offset >= 0) { /* Code the number of the string containing * the raw bytecode. */
c81ab42005-11-21Henrik Grubbström (Grubba)  code_number(read_program_data(p->program + id->func.offset, -1), data);
82723d2003-11-25Henrik Grubbström (Grubba)  } else { /* Prototype */ code_number(-1, data); } #else /* !PIKE_PORTABLE_BYTECODE */
9182912002-05-10Henrik Grubbström (Grubba)  code_number(id->func.offset, data);
82723d2003-11-25Henrik Grubbström (Grubba) #endif /* PIKE_PORTABLE_BYTECODE */
9182912002-05-10Henrik Grubbström (Grubba)  /* opt_flags */ code_number(id->opt_flags, data);
53ccc82003-08-03Martin Stjernholm  break; case IDENTIFIER_C_FUNCTION:
272fe82013-06-16Henrik Grubbström (Grubba)  if (is_variant_dispatcher(p, d)) { /* This is handled by end_first_pass() et all. */ /* NB: This can be reached even though id_dumped * for it gets set by the variant functions, * if it is overriding an old definition. * * We thus need to make sure id_dumped stays cleared. */ id_dumped[ref->identifier_offset] = 0; continue; }
9182912002-05-10Henrik Grubbström (Grubba)  /* Not supported. */ Pike_error("Cannot encode functions implemented in C "
9606eb2004-11-12Henrik Grubbström (Grubba)  "(identifier=\"%S\").\n",
49a3442009-08-19Henrik Grubbström (Grubba)  id->name);
53ccc82003-08-03Martin Stjernholm  break; case IDENTIFIER_VARIABLE:
49a3442009-08-19Henrik Grubbström (Grubba)  if (d < d_min) { EDB(3, fprintf(stderr, "%*sencode: Skipping overloaded variable \"%s\"\n", data->depth, "", id->name->str)); /* We still want to dump it later... */ id_dumped[ref->identifier_offset] = 0; goto next_identifier_ref; }
9182912002-05-10Henrik Grubbström (Grubba)  EDB(3, fprintf(stderr, "%*sencode: encoding variable\n", data->depth, ""));
aafd5d2008-02-14Henrik Grubbström (Grubba)  encode_entry_variable:
9182912002-05-10Henrik Grubbström (Grubba)  code_number(ID_ENTRY_VARIABLE, data);
2704c22006-10-27Henrik Grubbström (Grubba)  if (gs_flags >= 0) { code_number(gs_flags, data); } else { code_number(ref->id_flags, data); }
9182912002-05-10Henrik Grubbström (Grubba)  /* name */ str_sval.u.string = id->name;
8d37f12003-06-03Martin Stjernholm  encode_value2(&str_sval, data, 0);
9182912002-05-10Henrik Grubbström (Grubba)  /* type */ ref_push_type_value(id->type);
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1, data, 0);
9182912002-05-10Henrik Grubbström (Grubba)  pop_stack();
865d652008-05-16Henrik Grubbström (Grubba)  /* filename */ code_number(id->filename_strno, data); /* linenumber */ code_number(id->linenumber, data);
53ccc82003-08-03Martin Stjernholm  break; #ifdef PIKE_DEBUG
eb291b2013-02-16Henrik Grubbström (Grubba)  default:
76a9bd2007-01-05Henrik Grubbström (Grubba)  Pike_fatal ("Unknown identifier type: 0x%04x for symbol \"%s\".\n", id->identifier_flags & IDENTIFIER_TYPE_MASK, id->name->str);
53ccc82003-08-03Martin Stjernholm #endif
9182912002-05-10Henrik Grubbström (Grubba)  } } /* Identifier reference number */ code_number(d, data); next_identifier_ref: ; /* C requires a statement after lables. */ #ifdef ENCODE_DEBUG data->depth -= 2; #endif } /* Encode next inherit. */ if (inherit_num < p->num_inherits) { /* Inherit */
54e6c42008-02-08Henrik Grubbström (Grubba)  /* Flags that have been set by/after the inherit. */ INT16 inherit_flags_set = 0; /* Mask of flags that may have been affected by * the inherit. */ INT16 inherit_flags_mask = ~(ID_HIDDEN|ID_INHERITED);
9182912002-05-10Henrik Grubbström (Grubba)  struct inherit *inh = p->inherits + inherit_num; struct reference *ref = p->identifier_references + d; int i;
49a3442009-08-19Henrik Grubbström (Grubba)  /* The references from this inherit stop at this point. */ d_min = inh->identifier_level + inh->prog->num_identifier_references;
9182912002-05-10Henrik Grubbström (Grubba)  EDB(3, fprintf(stderr, "%*sencode: encoding inherit\n", data->depth, "")); #ifdef ENCODE_DEBUG data->depth += 2; #endif code_number(ID_ENTRY_INHERIT, data); /* Calculate id_flags */ for (i = 0; i < inh->prog->num_identifier_references; i++) { if (ref[i].inherit_offset) {
54e6c42008-02-08Henrik Grubbström (Grubba)  INT16 id_flags = ref[i].id_flags; INT16 inh_id_flags =
9182912002-05-10Henrik Grubbström (Grubba)  inh->prog->identifier_references[i].id_flags;
54e6c42008-02-08Henrik Grubbström (Grubba)  /* Ignore identifiers that have been hidden. */ if (!(id_flags & ID_HIDDEN)) { inherit_flags_set |= id_flags & ~inh_id_flags; if (inh_id_flags & ID_PUBLIC) { /* Public symbols aren't affected by a * private inherit. */ inherit_flags_mask &= id_flags | ID_PRIVATE; } else { inherit_flags_mask &= id_flags; } } } else { /* If an inherited identifiers has been overloaded, * it can not have been a local inherit. */ inherit_flags_mask &= ~ID_LOCAL;
9182912002-05-10Henrik Grubbström (Grubba)  } } EDB(5,
54e6c42008-02-08Henrik Grubbström (Grubba)  fprintf(stderr, "%*sraw inherit_flags_set: %04x:%04x\n", data->depth, "", inherit_flags_set, inherit_flags_mask)); inherit_flags_set &= inherit_flags_mask; code_number(inherit_flags_set, data);
9182912002-05-10Henrik Grubbström (Grubba)  EDB(5, fprintf(stderr, "%*sinherit_flags: %04x\n",
8a45852008-02-26Henrik Grubbström (Grubba)  data->depth, "", inherit_flags_set));
9182912002-05-10Henrik Grubbström (Grubba)  /* Identifier reference level at insertion. */ code_number(d_max, data); /* name */
e7663e2014-03-19Arne Goedeke  if (!inh->name) Pike_error("Cannot encode programs with unnamed inherits.\n");
9182912002-05-10Henrik Grubbström (Grubba)  str_sval.u.string = inh->name;
8d37f12003-06-03Martin Stjernholm  encode_value2(&str_sval, data, 0);
9182912002-05-10Henrik Grubbström (Grubba)  /* prog */ ref_push_program(inh->prog);
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1, data, 1);
9182912002-05-10Henrik Grubbström (Grubba)  pop_stack(); /* parent */ if (inh->parent) { ref_push_object(inh->parent); } else { push_int(0); }
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1, data, 0);
9182912002-05-10Henrik Grubbström (Grubba)  pop_stack(); /* parent_identifier */ code_number(inh->parent_identifier, data); /* parent_offset */ code_number(inh->parent_offset, data); /* Number of identifier references. */ code_number(inh->prog->num_identifier_references, data); inherit_num += inh->prog->num_inherits; #ifdef ENCODE_DEBUG data->depth -= 2; #endif } } /* End-marker */ code_number(ID_ENTRY_EOT, data); #ifdef ENCODE_DEBUG data->depth -= 2; #endif } /* Encode the constant values table. */ { struct svalue str_sval;
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(str_sval, T_STRING, 0, string, NULL);
9182912002-05-10Henrik Grubbström (Grubba) 
0a8db82013-11-07Henrik Grubbström (Grubba)  EDB(2, fprintf(stderr, "%*sencode: encoding constants\n", data->depth, ""));
9182912002-05-10Henrik Grubbström (Grubba)  /* constants */ for(d=0;d<p->num_constants;d++) {
0a8db82013-11-07Henrik Grubbström (Grubba)  EDB(5, fprintf(stderr, "%*sencode: encoding constant #%d\n", data->depth, "", d));
35892c2003-11-25Henrik Grubbström (Grubba) #ifdef PIKE_PORTABLE_BYTECODE
017b572011-10-28Henrik Grubbström (Grubba)  if (((TYPEOF(p->constants[d].sval) == T_FUNCTION) && (SUBTYPEOF(p->constants[d].sval) == FUNCTION_BUILTIN)) || (TYPEOF(p->constants[d].sval) == T_TYPE)) {
35892c2003-11-25Henrik Grubbström (Grubba)  /* Already encoded above. */ continue; } #endif /* PIKE_PORTABLE_BYTECODE */
9182912002-05-10Henrik Grubbström (Grubba)  /* value */
fe0b712003-06-12Martin Stjernholm  encode_value2(&p->constants[d].sval, data, 0);
9182912002-05-10Henrik Grubbström (Grubba)  /* name */
4ea54f2004-05-29Henrik Grubbström (Grubba) #if 0
9182912002-05-10Henrik Grubbström (Grubba)  if (p->constants[d].name) { str_sval.u.string = p->constants[d].name;
8d37f12003-06-03Martin Stjernholm  encode_value2(&str_sval, data, 0);
9182912002-05-10Henrik Grubbström (Grubba)  } else {
4ea54f2004-05-29Henrik Grubbström (Grubba) #endif /* 0 */
9182912002-05-10Henrik Grubbström (Grubba)  push_int(0);
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1, data, 0);
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp-1);
9182912002-05-10Henrik Grubbström (Grubba)  Pike_sp--;
4ea54f2004-05-29Henrik Grubbström (Grubba) #if 0
9182912002-05-10Henrik Grubbström (Grubba)  }
4ea54f2004-05-29Henrik Grubbström (Grubba) #endif /* 0 */
9182912002-05-10Henrik Grubbström (Grubba)  } } #endif /* OLD_PIKE_ENCODE_PROGRAM */
05590d1998-04-23Fredrik Hübinette (Hubbe)  }else{
974a3f2001-08-11Henrik Grubbström (Grubba)  code_entry(TAG_PROGRAM, 0, data);
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-1, data, 0); pop_stack();
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
e893d12001-07-02Martin Stjernholm  }
3ad9861997-01-26Fredrik Hübinette (Hubbe)  }
b55a122001-07-10Martin Stjernholm 
3beae42003-06-02Martin Stjernholm encode_done:;
b55a122001-07-10Martin 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);
a63ecd2011-03-19Martin Stjernholm  if (data->codec) free_object (data->codec);
3ad9861997-01-26Fredrik Hübinette (Hubbe)  free_mapping(data->encoded);
8d37f12003-06-03Martin Stjernholm  free_array(data->delayed);
3ad9861997-01-26Fredrik Hübinette (Hubbe) }
3236402004-12-18Henrik Grubbström (Grubba) /*! @decl string encode_value(mixed value, Codec|void codec)
f2bd922001-02-01Henrik Grubbström (Grubba)  *! *! Code a value into a string. *! *! This function takes a value, and converts it to a string. This string *! can then be saved, sent to another Pike process, packed or used in *! any way you like. When you want your value back you simply send this *! string to @[decode_value()] and it will return the value you encoded. *! *! Almost any value can be coded, mappings, floats, arrays, circular *! structures etc. *!
a63ecd2011-03-19Martin Stjernholm  *! If @[codec] is specified, it's used as the codec for the encode. *! If none is specified, then one is instantiated through *! @expr{master()->Encoder()@}. As a compatibility fallback, the *! master itself is used if it has no @expr{Encoder@} class.
e893d12001-07-02Martin Stjernholm  *!
b3eace2008-10-02Martin Stjernholm  *! If @expr{@[codec]->nameof(o)@} returns @tt{UNDEFINED@} for an *! object, @expr{val = o->encode_object(o)@} will be called. The *! returned value will be passed to @expr{o->decode_object(o, val)@} *! when the object is decoded.
3236402004-12-18Henrik Grubbström (Grubba)  *!
e893d12001-07-02Martin Stjernholm  *! @note *! *! When only simple types like int, floats, strings, mappings, *! multisets and arrays are encoded, the produced string is very *! portable between pike versions. It can at least be read by any *! later version. *! *! The portability when objects, programs and functions are involved *! depends mostly on the codec. If the byte code is encoded, i.e. *! when Pike programs are actually dumped in full, then the string *! can probably only be read by the same pike version.
f2bd922001-02-01Henrik Grubbström (Grubba)  *! *! @seealso *! @[decode_value()], @[sprintf()], @[encode_value_canonic()] */
3ad9861997-01-26Fredrik Hübinette (Hubbe) void f_encode_value(INT32 args) { ONERROR tmp; struct encode_data d, *data;
8d37f12003-06-03Martin Stjernholm  int i;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  data=&d;
583ade2000-02-16Per Hedbor 
8a86892003-06-05Martin Stjernholm  check_all_args("encode_value", args, BIT_MIXED, BIT_VOID | BIT_OBJECT | BIT_ZERO,
53ab182002-05-02Martin Stjernholm #ifdef ENCODE_DEBUG /* This argument is only an internal debug helper. * It's intentionally not part of the function * prototype, to keep the argument position free for * other uses in the future. */ BIT_VOID | BIT_INT, #endif 0);
3ad9861997-01-26Fredrik Hübinette (Hubbe)  initialize_buf(&data->buf);
657a002000-03-26Martin Stjernholm  data->canonic = 0; data->encoded=allocate_mapping(128);
8d37f12003-06-03Martin Stjernholm  data->delayed = allocate_array (0);
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(data->counter, T_INT, NUMBER_NUMBER, integer, COUNTER_START);
e212202003-06-05Martin Stjernholm  #ifdef ENCODE_DEBUG data->debug = args > 2 ? Pike_sp[2-args].u.integer : 0; data->depth = -2; #endif
017b572011-10-28Henrik Grubbström (Grubba)  if(args > 1 && TYPEOF(Pike_sp[1-args]) == T_OBJECT)
657a002000-03-26Martin Stjernholm  {
017b572011-10-28Henrik Grubbström (Grubba)  if (SUBTYPEOF(Pike_sp[1-args])) {
c2df122004-12-18Henrik Grubbström (Grubba)  Pike_error("encode_value: " "The codec may not be a subtyped object yet.\n"); }
fc26f62000-07-06Fredrik Hübinette (Hubbe)  data->codec=Pike_sp[1-args].u.object;
5929862011-03-19Martin Stjernholm  add_ref (data->codec);
657a002000-03-26Martin Stjernholm  }else{
a63ecd2011-03-19Martin Stjernholm  data->codec=NULL;
657a002000-03-26Martin Stjernholm  } SET_ONERROR(tmp, free_encode_data, data); addstr("\266ke0", 4);
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-args, data, 1); for (i = 0; i < data->delayed->size; i++) encode_value2 (ITEM(data->delayed) + i, data, 2);
657a002000-03-26Martin Stjernholm  UNSET_ONERROR(tmp);
a63ecd2011-03-19Martin Stjernholm  if (data->codec) free_object (data->codec);
657a002000-03-26Martin Stjernholm  free_mapping(data->encoded);
09a0d02003-06-05Martin Stjernholm  free_array (data->delayed);
657a002000-03-26Martin Stjernholm  pop_n_elems(args); push_string(low_free_buf(&data->buf)); }
53ab182002-05-02Martin Stjernholm /*! @decl string encode_value_canonic(mixed value, object|void codec)
f2bd922001-02-01Henrik Grubbström (Grubba)  *! *! Code a value into a string on canonical form. *! *! Takes a value and converts it to a string on canonical form, much like *! @[encode_value()]. The canonical form means that if an identical value is *! encoded, it will produce exactly the same string again, even if it's *! done at a later time and/or in another Pike process. The produced *! string is compatible with @[decode_value()]. *! *! @note *! Note that this function is more restrictive than @[encode_value()] with *! respect to the types of values it can encode. It will throw an error *! if it can't encode to a canonical form. *! *! @seealso *! @[encode_value()], @[decode_value()] */
657a002000-03-26Martin Stjernholm void f_encode_value_canonic(INT32 args) { ONERROR tmp; struct encode_data d, *data;
8d37f12003-06-03Martin Stjernholm  int i;
657a002000-03-26Martin Stjernholm  data=&d;
b55a122001-07-10Martin Stjernholm 
8fb4b62003-06-05Martin Stjernholm  check_all_args("encode_value_canonic", args, BIT_MIXED, BIT_VOID | BIT_OBJECT | BIT_ZERO,
53ab182002-05-02Martin Stjernholm #ifdef ENCODE_DEBUG /* This argument is only an internal debug helper. * It's intentionally not part of the function * prototype, to keep the argument position free for * other uses in the future. */ BIT_VOID | BIT_INT, #endif 0);
657a002000-03-26Martin Stjernholm  initialize_buf(&data->buf); data->canonic = 1;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  data->encoded=allocate_mapping(128);
8d37f12003-06-03Martin Stjernholm  data->delayed = allocate_array (0);
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(data->counter, T_INT, NUMBER_NUMBER, integer, COUNTER_START);
e212202003-06-05Martin Stjernholm  #ifdef ENCODE_DEBUG data->debug = args > 2 ? Pike_sp[2-args].u.integer : 0; data->depth = -2; #endif
017b572011-10-28Henrik Grubbström (Grubba)  if(args > 1 && TYPEOF(Pike_sp[1-args]) == T_OBJECT)
05590d1998-04-23Fredrik Hübinette (Hubbe)  {
017b572011-10-28Henrik Grubbström (Grubba)  if (SUBTYPEOF(Pike_sp[1-args])) {
c2df122004-12-18Henrik Grubbström (Grubba)  Pike_error("encode_value_canonic: " "The codec may not be a subtyped object yet.\n"); }
fc26f62000-07-06Fredrik Hübinette (Hubbe)  data->codec=Pike_sp[1-args].u.object;
5929862011-03-19Martin Stjernholm  add_ref (data->codec);
05590d1998-04-23Fredrik Hübinette (Hubbe)  }else{
a63ecd2011-03-19Martin Stjernholm  data->codec=NULL;
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
3ad9861997-01-26Fredrik Hübinette (Hubbe)  SET_ONERROR(tmp, free_encode_data, data); addstr("\266ke0", 4);
8d37f12003-06-03Martin Stjernholm  encode_value2(Pike_sp-args, data, 1); for (i = 0; i < data->delayed->size; i++) encode_value2 (ITEM(data->delayed) + i, data, 2);
3ad9861997-01-26Fredrik Hübinette (Hubbe)  UNSET_ONERROR(tmp);
a63ecd2011-03-19Martin Stjernholm  if (data->codec) free_object (data->codec);
3ad9861997-01-26Fredrik Hübinette (Hubbe)  free_mapping(data->encoded);
09a0d02003-06-05Martin Stjernholm  free_array (data->delayed);
05590d1998-04-23Fredrik Hübinette (Hubbe) 
3ad9861997-01-26Fredrik Hübinette (Hubbe)  pop_n_elems(args); push_string(low_free_buf(&data->buf)); }
20d57c2001-07-02Fredrik Hübinette (Hubbe)  struct unfinished_prog_link { struct unfinished_prog_link *next; struct program *prog; };
6f7ff82001-07-12Fredrik Hübinette (Hubbe) struct unfinished_obj_link {
d4c6c12001-07-15Martin Stjernholm  struct unfinished_obj_link *next;
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  struct object *o;
478c7d2008-05-21Henrik Grubbström (Grubba)  struct svalue decode_arg;
6f7ff82001-07-12Fredrik Hübinette (Hubbe) };
3ad9861997-01-26Fredrik Hübinette (Hubbe) struct decode_data {
32789f2005-05-31Martin Stjernholm  struct pike_string *data_str;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  unsigned char *data;
f00c362000-08-10Henrik Grubbström (Grubba)  ptrdiff_t len; ptrdiff_t ptr;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  struct mapping *decoded;
20d57c2001-07-02Fredrik Hübinette (Hubbe)  struct unfinished_prog_link *unfinished_programs;
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  struct unfinished_obj_link *unfinished_objects;
0efe6b2008-05-26Henrik Grubbström (Grubba)  struct unfinished_obj_link *unfinished_placeholders;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  struct svalue counter;
05590d1998-04-23Fredrik Hübinette (Hubbe)  struct object *codec;
a63ecd2011-03-19Martin Stjernholm  int explicit_codec;
05590d1998-04-23Fredrik Hübinette (Hubbe)  int pickyness;
997a002001-11-08Fredrik Hübinette (Hubbe)  int pass;
0efe6b2008-05-26Henrik Grubbström (Grubba)  int delay_counter;
a72ad72001-07-03Henrik Grubbström (Grubba)  struct pike_string *raw; struct decode_data *next;
d45dce2001-08-14Martin Stjernholm #ifdef PIKE_THREADS
0431312003-02-15Henrik Grubbström (Grubba)  struct thread_state *thread_state;
32789f2005-05-31Martin Stjernholm  struct object *thread_obj;
d45dce2001-08-14Martin Stjernholm #endif
b55a122001-07-10Martin Stjernholm #ifdef ENCODE_DEBUG int debug, depth; #endif
32789f2005-05-31Martin Stjernholm #if TWO_PASS_DECODE_WORKS /* The delay stuff can trig a second pass through the decoder, * but it doesn't seem to really handle that. /mast */
997a002001-11-08Fredrik Hübinette (Hubbe)  struct Supporter supporter;
32789f2005-05-31Martin Stjernholm #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe) };
a63ecd2011-03-19Martin Stjernholm static struct object *decoder_codec (struct decode_data *data) { struct pike_string *decoder_str; if (data->codec) return data->codec; MAKE_CONST_STRING (decoder_str, "Decoder"); return data->codec = lookup_codec (decoder_str); }
fe0b712003-06-12Martin Stjernholm static void decode_value2(struct decode_data *data);
05590d1998-04-23Fredrik Hübinette (Hubbe) 
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)
2ac4992011-03-09Martin Stjernholm  Pike_error("Decode error: Not enough data in string.\n");
3ad9861997-01-26Fredrik Hübinette (Hubbe)  return data->data [ data->ptr++ ]; }
2ac4992011-03-09Martin Stjernholm static DECLSPEC(noreturn) void decode_error ( struct decode_data *data, struct svalue *decoding, const char *msg, ...) ATTRIBUTE((noreturn)); static DECLSPEC(noreturn) void decode_error ( struct decode_data *data, struct svalue *decoding, const char *msg, ...) { int n = 0; va_list args; struct string_builder sb; struct object *o = fast_clone_object (decode_error_program); struct decode_error_struct *dec = (struct decode_error_struct *) (o->storage + decode_error_offset); struct generic_error_struct *gen = (struct generic_error_struct *) get_storage (o, generic_error_program); ASSERT_THREAD_SWAPPED_IN(); copy_shared_string (dec->decode_string, data->data_str); if (decoding) { push_constant_text ("Error while decoding "); n++; push_constant_text ("%O"); push_svalue (decoding); f_sprintf (2); n++; push_constant_text (":\n"); n++; } else { push_constant_text ("Decode error: "); n++; } init_string_builder (&sb, 0); va_start (args, msg); string_builder_vsprintf (&sb, msg, args); va_end (args); push_string (finish_string_builder (&sb)); n++; f_add (n); gen->error_message = (--Pike_sp)->u.string; generic_error_va (o, NULL, NULL, 0, NULL, NULL); }
3ad9861997-01-26Fredrik Hübinette (Hubbe) #define GETC() my_extract_char(data)
52bb181999-10-25Fredrik Hübinette (Hubbe) #define DECODE(Z) do { \
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  EDB(5, \
b55a122001-07-10Martin Stjernholm  fprintf(stderr,"%*sdecode(%s) at %d: ", \ data->depth,"",(Z),__LINE__)); \
52bb181999-10-25Fredrik Hübinette (Hubbe)  what=GETC(); \ e=what>>SIZE_SHIFT; \
4ba6be1999-12-11Henrik Grubbström (Grubba)  if(what & TAG_SMALL) { \
52bb181999-10-25Fredrik Hübinette (Hubbe)  num=e; \ } else { \
adf01a2008-06-11Henrik Grubbström (Grubba)  num = 0; \
7ce7f52014-01-11Tobias S. Josefowitz  while(e-->=0) num = ((unsigned INT64)num<<8) \ + (GETC()+1); \
adf01a2008-06-11Henrik Grubbström (Grubba)  num += MAX_SMALL - 1; \
be273a2000-09-11Henrik Grubbström (Grubba)  } \ if(what & TAG_NEG) { \ num = ~num; \
52bb181999-10-25Fredrik Hübinette (Hubbe)  } \
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  EDB(5, \
adf01a2008-06-11Henrik Grubbström (Grubba)  fprintf(stderr,"type=%d (%s), num=%ld\n", \ (what & TAG_MASK), \ get_name_of_type(tag_to_type(what & TAG_MASK)), \ (long)num) ); \
583ade2000-02-16Per Hedbor } while (0)
52bb181999-10-25Fredrik Hübinette (Hubbe) 
05590d1998-04-23Fredrik Hübinette (Hubbe) #define decode_entry(X,Y,Z) \ do { \
adf01a2008-06-11Henrik Grubbström (Grubba)  INT32 what, e; \ INT64 num; \
be273a2000-09-11Henrik Grubbström (Grubba)  DECODE("decode_entry"); \ if((what & TAG_MASK) != (X)) \
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Wrong bits (%d).\n", what & TAG_MASK); \ (Y)=num; \
05590d1998-04-23Fredrik Hübinette (Hubbe)  } while(0); #define getdata2(S,L) do { \
ae558d2014-03-12Arne Goedeke  if(sizeof(S[0])*(L) > (size_t)(data->len - data->ptr)) \
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "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)
3e9b112011-01-26Arne Goedeke #if PIKE_BYTEORDER == 4321
b9a7b01999-09-18Fredrik Hübinette (Hubbe) #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) \ { \
adf01a2008-06-11Henrik Grubbström (Grubba)  INT32 what, e; \ INT64 num; \
1f7cb82008-02-06Martin Stjernholm  ptrdiff_t sz; \
52bb181999-10-25Fredrik Hübinette (Hubbe)  DECODE("get_string_data"); \
be273a2000-09-11Henrik Grubbström (Grubba)  what &= TAG_MASK; \ if(what<0 || what>2) \
2ac4992011-03-09Martin Stjernholm  decode_error (data, NULL, "Illegal size shift %d.\n", what); \
1f7cb82008-02-06Martin Stjernholm  sz = (ptrdiff_t) num << what; \ if (sz < 0) \
2ac4992011-03-09Martin Stjernholm  decode_error (data, NULL, "Illegal negative size %td.\n", sz); \
1f7cb82008-02-06Martin Stjernholm  if (sz > data->len - data->ptr) \
2ac4992011-03-09Martin Stjernholm  decode_error (data, NULL, "Too large size %td (max is %td).\n", \ sz, data->len - data->ptr); \
1f7cb82008-02-06Martin Stjernholm  STR=begin_wide_shared_string(num, what); \ MEMCPY(STR->str, data->data + data->ptr, sz); \ data->ptr += sz; \
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  BITFLIP(STR); \ STR=end_shared_string(STR); \ }else{ \
1f7cb82008-02-06Martin Stjernholm  ptrdiff_t sz = (LEN); \ if (sz < 0) \
2ac4992011-03-09Martin Stjernholm  decode_error (data, NULL, "Illegal negative size %td.\n", sz); \
1f7cb82008-02-06Martin Stjernholm  if (sz > data->len - data->ptr) \
2ac4992011-03-09Martin Stjernholm  decode_error (data, NULL, "Too large size %td (max is %td).\n", \ sz, data->len - data->ptr); \
1f7cb82008-02-06Martin Stjernholm  STR=make_shared_binary_string((char *)(data->data + data->ptr), sz); \ data->ptr += sz; \
b9a7b01999-09-18Fredrik Hübinette (Hubbe)  } \ }while(0) #define getdata(X) do { \ long length; \
4ba6be1999-12-11Henrik Grubbström (Grubba)  decode_entry(TAG_STRING, length,data); \
997a002001-11-08Fredrik Hübinette (Hubbe)  if(data->pass == 1) \ get_string_data(X, length, data); \ else \ data->ptr+=length; \
05590d1998-04-23Fredrik Hübinette (Hubbe)  }while(0)
11b69f1999-09-17Fredrik Hübinette (Hubbe) #define getdata3(X) do { \
adf01a2008-06-11Henrik Grubbström (Grubba)  INT32 what, e; \ INT64 num; \
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: \
2ac4992011-03-09Martin Stjernholm  decode_error (data, NULL, "Tag is wrong: %d\n", what & TAG_MASK); \
11b69f1999-09-17Fredrik Hübinette (Hubbe)  } \ }while(0)
adf01a2008-06-11Henrik Grubbström (Grubba) #define decode_number(X,data) do { \ INT32 what, e; \ INT64 num; \
52bb181999-10-25Fredrik Hübinette (Hubbe)  DECODE("decode_number"); \
7ce7f52014-01-11Tobias S. Josefowitz  X=(what & TAG_MASK) | ((unsigned INT64)num<<4); \
3beae42003-06-02Martin Stjernholm  EDB(5, fprintf(stderr, "%*s ==>%ld\n", \ data->depth, "", (long) X)); \
05590d1998-04-23Fredrik Hübinette (Hubbe)  }while(0) \
8174c82001-03-03Henrik Grubbström (Grubba) static void restore_type_stack(struct pike_type **old_stackp)
770c7d1999-11-03Henrik Grubbström (Grubba) { #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) {
5aad932002-08-15Marcus Comstedt  Pike_fatal("type stack out of sync!\n");
770c7d1999-11-03Henrik Grubbström (Grubba)  } #endif /* PIKE_DEBUG */
da652c2001-05-13Fredrik Hübinette (Hubbe)  while(Pike_compiler->type_stackp > old_stackp) { free_type(*(Pike_compiler->type_stackp--)); }
770c7d1999-11-03Henrik Grubbström (Grubba) }
8174c82001-03-03Henrik Grubbström (Grubba) static void restore_type_mark(struct pike_type ***old_type_mark_stackp)
770c7d1999-11-03Henrik Grubbström (Grubba) { #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) {
5aad932002-08-15Marcus Comstedt  Pike_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) 
f777702000-02-09Henrik Grubbström (Grubba)  tmp = GETC();
de91672013-06-12Henrik Grubbström (Grubba)  if (tmp <= MAX_TYPE) tmp ^= MIN_REF_TYPE;
05590d1998-04-23Fredrik Hübinette (Hubbe)  switch(tmp) { default:
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Error in type string (%d).\n", tmp);
05590d1998-04-23Fredrik Hübinette (Hubbe)  /*NOTREACHED*/ break;
583ade2000-02-16Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_ASSIGN:
9e6f6f2001-03-18Henrik Grubbström (Grubba)  tmp = GETC(); if ((tmp < '0') || (tmp > '9')) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Bad marker in type string (%d).\n", tmp);
9e6f6f2001-03-18Henrik Grubbström (Grubba)  }
8174c82001-03-03Henrik Grubbström (Grubba)  low_decode_type(data);
9e6f6f2001-03-18Henrik Grubbström (Grubba)  push_assign_type(tmp); /* Actually reverse, but they're the same */
8174c82001-03-03Henrik Grubbström (Grubba)  break;
583ade2000-02-16Per Hedbor 
159fdf2007-05-09Henrik Grubbström (Grubba)  case T_SCOPE: tmp = GETC(); low_decode_type(data); push_scope_type(tmp); /* Actually reverse, but they're the same */ break;
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_FUNCTION:
8174c82001-03-03Henrik Grubbström (Grubba)  { int narg = 0; while (GETC() != T_MANY) { data->ptr--; low_decode_type(data); narg++; } low_decode_type(data); /* Many */ low_decode_type(data); /* Return */ push_reverse_type(T_MANY); while(narg-- > 0) { push_reverse_type(T_FUNCTION); } } break;
583ade2000-02-16Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_MAPPING: case T_OR: case T_AND:
8174c82001-03-03Henrik Grubbström (Grubba)  low_decode_type(data); low_decode_type(data); push_reverse_type(tmp); break;
05590d1998-04-23Fredrik Hübinette (Hubbe) 
54f8ac2001-03-17Henrik Grubbström (Grubba)  case T_TYPE:
8c953a2001-03-28Henrik Grubbström (Grubba)  case T_PROGRAM:
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_ARRAY: case T_MULTISET: case T_NOT:
8174c82001-03-03Henrik Grubbström (Grubba)  low_decode_type(data); push_type(tmp); break;
2377dc1999-03-07Henrik Grubbström (Grubba)  case T_INT:
8174c82001-03-03Henrik Grubbström (Grubba)  { INT32 min=0, max=0;
1db77c2014-01-11Tobias S. Josefowitz  if(data->ptr + 8 > data->len)
db7fe62014-03-12Arne Goedeke  decode_error(data, NULL, "Not enough data.\n");
1db77c2014-01-11Tobias S. Josefowitz  min = get_unaligned_be32(data->data + data->ptr); data->ptr += 4; max = get_unaligned_be32(data->data + data->ptr); data->ptr += 4;
db7fe62014-03-12Arne Goedeke  if (min > max) decode_error(data, NULL, "Error in int type (min (%d) > max (%d)).\n", min, max);
8174c82001-03-03Henrik Grubbström (Grubba)  push_int_type(min, max); }
2377dc1999-03-07Henrik Grubbström (Grubba)  break;
157fc62007-03-03Henrik Grubbström (Grubba)  case T_STRING: /* Common case and compat */
4e6c082007-05-02Henrik Grubbström (Grubba)  push_finished_type(int_type_string); push_type(T_STRING);
157fc62007-03-03Henrik Grubbström (Grubba)  break; case PIKE_T_NSTRING: {
4e6c082007-05-02Henrik Grubbström (Grubba)  low_decode_type(data); push_type(T_STRING);
157fc62007-03-03Henrik Grubbström (Grubba)  } 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_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:
3611422001-02-20Henrik Grubbström (Grubba)  push_type(tmp);
05590d1998-04-23Fredrik Hübinette (Hubbe)  break;
583ade2000-02-16Per Hedbor 
2f1cde2007-04-26Henrik Grubbström (Grubba)  case PIKE_T_ATTRIBUTE: decode_value2(data);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) != PIKE_T_STRING) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Type attribute is not a string: %O\n", Pike_sp - 1);
2f1cde2007-04-26Henrik Grubbström (Grubba)  } low_decode_type(data); push_type_attribute(Pike_sp[-1].u.string); pop_stack(); break;
418a4a2002-11-22Henrik Grubbström (Grubba)  case PIKE_T_NAME:
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
418a4a2002-11-22Henrik Grubbström (Grubba) 
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) != PIKE_T_STRING) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Type name is not a string: %O\n", Pike_sp - 1);
418a4a2002-11-22Henrik Grubbström (Grubba)  } low_decode_type(data); push_type_name(Pike_sp[-1].u.string); pop_stack(); break;
05590d1998-04-23Fredrik Hübinette (Hubbe)  case T_OBJECT: {
3611422001-02-20Henrik Grubbström (Grubba)  int flag = GETC();
770c7d1999-11-03Henrik Grubbström (Grubba) 
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
017b572011-10-28Henrik Grubbström (Grubba)  switch(TYPEOF(Pike_sp[-1]))
05590d1998-04-23Fredrik Hübinette (Hubbe)  { case T_INT:
e9ce612001-03-29Per Hedbor  push_object_type_backwards(flag, Pike_sp[-1].u.integer );
05590d1998-04-23Fredrik Hübinette (Hubbe)  break; case T_PROGRAM:
3611422001-02-20Henrik Grubbström (Grubba)  push_object_type_backwards(flag, 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;
017b572011-10-28Henrik Grubbström (Grubba)  if (SUBTYPEOF(Pike_sp[-1]) == FUNCTION_BUILTIN) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "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) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode object type.\n");
9b34321999-12-19Henrik Grubbström (Grubba)  }
f877222008-02-06Henrik Grubbström (Grubba)  debug_malloc_touch(prog);
3611422001-02-20Henrik Grubbström (Grubba)  push_object_type_backwards(flag, prog->id);
9b34321999-12-19Henrik Grubbström (Grubba)  } break;
05590d1998-04-23Fredrik Hübinette (Hubbe)  default:
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode type " "(object(%s), expected object(zero|program)).\n",
017b572011-10-28Henrik Grubbström (Grubba)  get_name_of_type(TYPEOF(Pike_sp[-1])));
05590d1998-04-23Fredrik Hübinette (Hubbe)  } pop_stack(); } }
770c7d1999-11-03Henrik Grubbström (Grubba)  UNSET_ONERROR(err2); UNSET_ONERROR(err1);
05590d1998-04-23Fredrik Hübinette (Hubbe) }
997a002001-11-08Fredrik Hübinette (Hubbe) 
fe0b712003-06-12Martin Stjernholm static void zap_placeholder(struct object *placeholder) { /* fprintf(stderr, "Destructing placeholder.\n"); */ if (placeholder->storage) { debug_malloc_touch(placeholder); destruct(placeholder); } else { free_program(placeholder->prog); placeholder->prog = NULL; debug_malloc_touch(placeholder); } free_object(placeholder); }
997a002001-11-08Fredrik Hübinette (Hubbe) static int init_placeholder(struct object *placeholder); #define SETUP_DECODE_MEMOBJ(TYPE, U, VAR, ALLOCATE,SCOUR) do { \ struct svalue *tmpptr; \
8d37f12003-06-03Martin Stjernholm  struct svalue tmp; \
997a002001-11-08Fredrik Hübinette (Hubbe)  if(data->pass > 1 && \
8d37f12003-06-03Martin Stjernholm  (tmpptr=low_mapping_lookup(data->decoded, & entry_id))) \
997a002001-11-08Fredrik Hübinette (Hubbe)  { \ tmp=*tmpptr; \ VAR=tmp.u.U; \
fe0b712003-06-12Martin Stjernholm  SCOUR; \
997a002001-11-08Fredrik Hübinette (Hubbe)  }else{ \
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(tmp, TYPE, 0, U, (VAR = ALLOCATE)); \
8d37f12003-06-03Martin Stjernholm  mapping_insert(data->decoded, & entry_id, &tmp); \
997a002001-11-08Fredrik Hübinette (Hubbe)  /* Since a reference to the object is stored in the mapping, we can \ * safely decrease this reference here. Thus it will be automatically \ * freed if something goes wrong. \ */ \
50ea682003-03-14Henrik Grubbström (Grubba)  sub_ref(VAR); \
997a002001-11-08Fredrik Hübinette (Hubbe)  } \ }while(0)
8174c82001-03-03Henrik Grubbström (Grubba) /* This really needs to disable threads.... */ #define decode_type(X,data) do { \ type_stack_mark(); \ low_decode_type(data); \ (X)=pop_unfinished_type(); \ } while(0)
50817d1997-10-07Fredrik Hübinette (Hubbe) 
57ed3f2012-12-30Jonas Walldén static void cleanup_new_program_decode (void *UNUSED(ignored))
7c57992003-02-24Martin Stjernholm {
f877222008-02-06Henrik Grubbström (Grubba)  debug_malloc_touch(Pike_compiler->new_program);
dc672b2008-02-08Henrik Grubbström (Grubba)  debug_malloc_touch(Pike_compiler->new_program->parent); /* The program is consistent enough to be freed... */
e2a1932008-02-08Henrik Grubbström (Grubba)  Pike_compiler->new_program->flags &= ~PROGRAM_AVOID_CHECK;
7c57992003-02-24Martin Stjernholm  end_first_pass(0); }
e614052008-05-17Henrik Grubbström (Grubba) static void restore_current_file(void *save_current_file) { struct compilation *c = THIS_COMPILATION; free_string(c->lex.current_file); c->lex.current_file = save_current_file; }
82723d2003-11-25Henrik Grubbström (Grubba) /* Decode bytecode string @[string_no]. * Returns resulting offset in p->program. */
2ac4992011-03-09Martin Stjernholm static INT32 decode_portable_bytecode(struct decode_data *data, INT32 string_no)
82723d2003-11-25Henrik Grubbström (Grubba) { struct program *p = Pike_compiler->new_program; struct pike_string *bytecode; struct pike_string *current_file=NULL;
ef24a82012-01-12Henrik Grubbström (Grubba)  INT_TYPE current_line = 0;
82723d2003-11-25Henrik Grubbström (Grubba)  int e; ONERROR err;
f877222008-02-06Henrik Grubbström (Grubba)  debug_malloc_touch(p);
82723d2003-11-25Henrik Grubbström (Grubba)  if ((string_no < 0) || (string_no >= p->num_strings)) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Bad bytecode string number: %d (expected 0 - %d).\n", string_no, p->num_strings-1);
82723d2003-11-25Henrik Grubbström (Grubba)  } bytecode = p->strings[string_no]; if (bytecode->len % 3) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Bad bytecode string length: " "%td (expected multiple of 3).\n", bytecode->len);
82723d2003-11-25Henrik Grubbström (Grubba)  } init_bytecode(); SET_ONERROR(err, exit_bytecode, NULL); switch(bytecode->size_shift) {
acadb52004-10-16Henrik Grubbström (Grubba) #define SIGNED_CHAR(X) X
9ba3042004-10-17Marcus Agehall  /* The EMIT_BYTECODE2 macro will generate the warning * "comparison is always false due to limited range of data type" * if used on STR0. Thus, the need to have two macros here. */ #define EMIT_BYTECODE2(STR) \ if (STR(bytecode)[e] == F_FILENAME) { \ INT32 strno = STR(bytecode)[e+1]; \ if (SIGNED_CHAR(strno < 0) || \ (strno >= p->num_strings)) { \
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Bad filename directive number:" \ " %d (expected 0 - %d).\n", \ strno, p->num_strings); \
9ba3042004-10-17Marcus Agehall  } \ current_file = p->strings[strno]; \ } else if (STR(bytecode)[e] == F_LINE) { \
ef24a82012-01-12Henrik Grubbström (Grubba)  current_line = \ ((unsigned INT32)STR(bytecode)[e+1]) | \ ((INT_TYPE)STR(bytecode)[e+2])<<32; \
91837d2008-01-17Henrik Grubbström (Grubba)  } else if (!current_file) { \
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Missing filename directive in " \ "byte code.\n"); \
91837d2008-01-17Henrik Grubbström (Grubba)  } else if (!current_line) { \
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Missing line directive in " \ "byte code.\n"); \
91837d2008-01-17Henrik Grubbström (Grubba)  } else
9ba3042004-10-17Marcus Agehall  #define EMIT_BYTECODE(STR, X) do { \ for (e = 0; e < bytecode->len; e += 3) { \ X(STR) \ { \ insert_opcode2(STR(bytecode)[e], \ STR(bytecode)[e+1], \ STR(bytecode)[e+2], \ current_line, \ current_file); \ } \ } \
82723d2003-11-25Henrik Grubbström (Grubba)  } while(0)
9ba3042004-10-17Marcus Agehall 
82723d2003-11-25Henrik Grubbström (Grubba)  case 2:
766bc82004-10-16Marcus Agehall  EMIT_BYTECODE(STR2, EMIT_BYTECODE2);
82723d2003-11-25Henrik Grubbström (Grubba)  break;
acadb52004-10-16Henrik Grubbström (Grubba) #undef SIGNED_CHAR
9ba3042004-10-17Marcus Agehall #define SIGNED_CHAR(X) 0
82723d2003-11-25Henrik Grubbström (Grubba)  case 1:
766bc82004-10-16Marcus Agehall  EMIT_BYTECODE(STR1, EMIT_BYTECODE2);
82723d2003-11-25Henrik Grubbström (Grubba)  break; case 0:
766bc82004-10-16Marcus Agehall #undef EMIT_BYTECODE2
441f4d2008-01-19Henrik Grubbström (Grubba) #define EMIT_BYTECODE2(X) \ if (!current_file) { \
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Missing filename directive in " \ "byte code.\n"); \
441f4d2008-01-19Henrik Grubbström (Grubba)  } else if (!current_line) { \
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Missing line directive in " \ "byte code.\n"); \
441f4d2008-01-19Henrik Grubbström (Grubba)  } else
766bc82004-10-16Marcus Agehall  EMIT_BYTECODE(STR0, EMIT_BYTECODE2);
82723d2003-11-25Henrik Grubbström (Grubba)  break;
acadb52004-10-16Henrik Grubbström (Grubba) #undef SIGNED_CHAR
82723d2003-11-25Henrik Grubbström (Grubba) #undef EMIT_BYTECODE
766bc82004-10-16Marcus Agehall #undef EMIT_BYTECODE2
c6b6042008-05-03Martin Nilsson #ifdef PIKE_DEBUG
82723d2003-11-25Henrik Grubbström (Grubba)  default: Pike_fatal("Bad size_shift: %d\n", bytecode->size_shift);
c6b6042008-05-03Martin Nilsson #endif
82723d2003-11-25Henrik Grubbström (Grubba)  } UNSET_ONERROR(err); return assemble(1); }
fe0b712003-06-12Martin Stjernholm 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
fe0b712003-06-12Martin Stjernholm #define decode_value2(X) do { struct svalue *_=Pike_sp; decode_value2_(X); if(Pike_sp!=_+1) Pike_fatal("decode_value2 failed!\n"); } while(0)
50817d1997-10-07Fredrik Hübinette (Hubbe) #endif
fe0b712003-06-12Martin Stjernholm 
3ad9861997-01-26Fredrik Hübinette (Hubbe) {
adf01a2008-06-11Henrik Grubbström (Grubba)  INT32 what, e; INT64 num;
8d37f12003-06-03Martin Stjernholm  struct svalue entry_id, *tmp2; struct svalue *delayed_enc_val;
583ade2000-02-16Per Hedbor 
b55a122001-07-10Martin Stjernholm #ifdef ENCODE_DEBUG data->depth += 2; #endif
eacf2c2010-02-11Henrik Grubbström (Grubba)  check_c_stack(1024);
52bb181999-10-25Fredrik Hübinette (Hubbe)  DECODE("decode_value2");
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  switch(what & TAG_MASK)
3ad9861997-01-26Fredrik Hübinette (Hubbe)  {
8d37f12003-06-03Martin Stjernholm  case TAG_DELAYED: EDB (2, fprintf(stderr, "%*sDecoding delay encoded from <%d>\n", data->depth, "", num););
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(entry_id, T_INT, NUMBER_NUMBER, integer, num);
8d37f12003-06-03Martin Stjernholm  if (!(delayed_enc_val = low_mapping_lookup (data->decoded, &entry_id)))
2ac4992011-03-09Martin Stjernholm  decode_error (data, NULL, "Failed to find previous record of " "delay encoded entry <%d>.\n", num);
8d37f12003-06-03Martin Stjernholm  DECODE ("decode_value2"); break;
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_AGAIN:
8d37f12003-06-03Martin Stjernholm  EDB (1, fprintf(stderr, "%*sDecoding TAG_AGAIN from <%d>\n", data->depth, "", num););
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(entry_id, T_INT, NUMBER_NUMBER, integer, num);
8d37f12003-06-03Martin Stjernholm  if((tmp2=low_mapping_lookup(data->decoded, &entry_id)))
50817d1997-10-07Fredrik Hübinette (Hubbe)  { push_svalue(tmp2); }else{
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode TAG_AGAIN entry <%d>.\n", num);
50817d1997-10-07Fredrik Hübinette (Hubbe)  }
8d37f12003-06-03Martin Stjernholm  goto decode_done;
583ade2000-02-16Per Hedbor 
8d37f12003-06-03Martin Stjernholm  default: entry_id = data->counter;
50817d1997-10-07Fredrik Hübinette (Hubbe)  data->counter.u.integer++;
8d37f12003-06-03Martin Stjernholm  /* Fall through. */ case TAG_TYPE: EDB (2, fprintf(stderr, "%*sDecoding to <%d>: TAG%d (%d)\n", data->depth, "", entry_id.u.integer , what & TAG_MASK, num);); /* Types are added to the encoded mapping AFTER they have been * encoded. */ delayed_enc_val = NULL; break; } check_stack(1); switch(what & TAG_MASK) { case TAG_INT:
50817d1997-10-07Fredrik Hübinette (Hubbe)  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; 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 
adf01a2008-06-11Henrik Grubbström (Grubba)  EDB(2,fprintf(stderr, "Decoding float... num:0x%016" PRINTINT64 "x\n", num));
be273a2000-09-11Henrik Grubbström (Grubba) 
adf01a2008-06-11Henrik Grubbström (Grubba)  res = (double)num;
be273a2000-09-11Henrik Grubbström (Grubba) 
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  EDB(2,fprintf(stderr, "Mantissa: %10g\n", res));
be273a2000-09-11Henrik Grubbström (Grubba) 
52bb181999-10-25Fredrik Hübinette (Hubbe)  DECODE("float");
be273a2000-09-11Henrik Grubbström (Grubba) 
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  EDB(2,fprintf(stderr, "Exponent: %d\n", num));
be273a2000-09-11Henrik Grubbström (Grubba) 
f335282001-08-08Fredrik Hübinette (Hubbe)  if(!res) { DECLARE_INF DECLARE_NAN switch(num) { case Pike_FP_SNAN: /* Signal Not A Number */ case Pike_FP_QNAN: /* Quiet Not A Number */
a5cd6a2001-09-24Henrik Grubbström (Grubba)  push_float(DO_NOT_WARN((FLOAT_TYPE)MAKE_NAN()));
f335282001-08-08Fredrik Hübinette (Hubbe)  break; case Pike_FP_NINF: /* Negative infinity */
a5cd6a2001-09-24Henrik Grubbström (Grubba)  push_float(DO_NOT_WARN((FLOAT_TYPE)MAKE_INF(-1)));
f335282001-08-08Fredrik Hübinette (Hubbe)  break; case Pike_FP_PINF: /* Positive infinity */
a5cd6a2001-09-24Henrik Grubbström (Grubba)  push_float(DO_NOT_WARN((FLOAT_TYPE)MAKE_INF(1)));
f335282001-08-08Fredrik Hübinette (Hubbe)  break; case Pike_FP_NZERO: /* Negative Zero */ push_float(-0.0); /* Does this do what we want? */ break; default:
a5cd6a2001-09-24Henrik Grubbström (Grubba)  push_float(DO_NOT_WARN((FLOAT_TYPE)LDEXP(res, num)));
f335282001-08-08Fredrik Hübinette (Hubbe)  break; } break; }
a5cd6a2001-09-24Henrik Grubbström (Grubba)  push_float(DO_NOT_WARN((FLOAT_TYPE)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)  {
cfc57e2001-02-22Henrik Grubbström (Grubba)  struct pike_type *t; decode_type(t, data); check_type_string(t); push_type_value(t);
8d37f12003-06-03Martin Stjernholm  entry_id = data->counter;
cfc57e2001-02-22Henrik Grubbström (Grubba)  data->counter.u.integer++;
69b77c1999-12-11Henrik Grubbström (Grubba)  }
cfc57e2001-02-22Henrik 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;
2523ce2003-04-28Martin Stjernholm  TYPE_FIELD types;
ab01ea1999-09-21Fredrik Hübinette (Hubbe)  if(num < 0)
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode array (array size is negative).\n");
ab01ea1999-09-21Fredrik Hübinette (Hubbe)  /* Heruetical */
ae558d2014-03-12Arne Goedeke  if(num > data->len - data->ptr)
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode array (not enough data).\n");
ab01ea1999-09-21Fredrik Hübinette (Hubbe) 
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  EDB(2,fprintf(stderr, "%*sDecoding array of size %d to <%d>\n",
8d37f12003-06-03Martin Stjernholm  data->depth, "", num, entry_id.u.integer));
583ade2000-02-16Per Hedbor 
fe0b712003-06-12Martin Stjernholm  SETUP_DECODE_MEMOBJ(T_ARRAY, array, a, allocate_array(num),
997a002001-11-08Fredrik Hübinette (Hubbe)  free_svalues(ITEM(a), a->size, a->type_field));
583ade2000-02-16Per Hedbor 
2523ce2003-04-28Martin Stjernholm  types = 0;
50817d1997-10-07Fredrik Hübinette (Hubbe)  for(e=0;e<num;e++) {
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
2523ce2003-04-28Martin Stjernholm  stack_pop_to_no_free (ITEM(a) + e);
017b572011-10-28Henrik Grubbström (Grubba)  types |= 1 << TYPEOF(ITEM(a)[e]);
50817d1997-10-07Fredrik Hübinette (Hubbe)  }
2523ce2003-04-28Martin Stjernholm  a->type_field = types;
d6ac731998-04-20Henrik Grubbström (Grubba)  ref_push_array(a);
8d37f12003-06-03Martin Stjernholm  goto decode_done;
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)
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode mapping " "(mapping size is negative).\n");
619d591997-12-22Fredrik Hübinette (Hubbe) 
dc672b2008-02-08Henrik Grubbström (Grubba)  /* Heuristical */
ae558d2014-03-12Arne Goedeke  if(num > data->len - data->ptr)
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode mapping " "(not enough data).\n");
ab01ea1999-09-21Fredrik Hübinette (Hubbe) 
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  EDB(2,fprintf(stderr, "%*sDecoding mapping of size %d to <%d>\n",
8d37f12003-06-03Martin Stjernholm  data->depth, "", num, entry_id.u.integer));
997a002001-11-08Fredrik Hübinette (Hubbe) 
fe0b712003-06-12Martin Stjernholm  SETUP_DECODE_MEMOBJ(T_MAPPING, mapping, m, allocate_mapping(num), ; );
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  for(e=0;e<num;e++) {
fe0b712003-06-12Martin Stjernholm  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);
8d37f12003-06-03Martin Stjernholm  goto decode_done;
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;
2523ce2003-04-28Martin Stjernholm  TYPE_FIELD types;
ab01ea1999-09-21Fredrik Hübinette (Hubbe)  if(num<0)
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode multiset " "(multiset size is negative).\n");
ab01ea1999-09-21Fredrik Hübinette (Hubbe)  /* Heruetical */
ae558d2014-03-12Arne Goedeke  if(num > data->len - data->ptr)
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "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...*/
997a002001-11-08Fredrik Hübinette (Hubbe) 
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  EDB(2,fprintf(stderr, "%*sDecoding multiset of size %d to <%d>\n",
8d37f12003-06-03Martin Stjernholm  data->depth, "", num, entry_id.u.integer));
5b15bb2001-12-10Martin Stjernholm  SETUP_DECODE_MEMOBJ (T_MULTISET, multiset, m,
fe0b712003-06-12Martin Stjernholm  allocate_multiset (0, 0, NULL), ;);
5b15bb2001-12-10Martin Stjernholm  /* FIXME: This array could be avoided by building the multiset directly. */ a = low_allocate_array (num, 0);
583ade2000-02-16Per Hedbor 
2523ce2003-04-28Martin Stjernholm  types = 0;
50817d1997-10-07Fredrik Hübinette (Hubbe)  for(e=0;e<num;e++) {
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
2523ce2003-04-28Martin Stjernholm  stack_pop_to_no_free (ITEM(a) + e);
017b572011-10-28Henrik Grubbström (Grubba)  types |= 1 << TYPEOF(ITEM(a)[e]);
50817d1997-10-07Fredrik Hübinette (Hubbe)  }
2523ce2003-04-28Martin Stjernholm  a->type_field = types;
5b15bb2001-12-10Martin Stjernholm  { struct multiset *l = mkmultiset (a); free_array (a); /* This special case is handled efficiently by merge_multisets. */ merge_multisets (m, l, PIKE_MERGE_DESTR_A | PIKE_ARRAY_OP_ADD); free_multiset (l); }
997a002001-11-08Fredrik Hübinette (Hubbe)  ref_push_multiset(m);
8d37f12003-06-03Martin Stjernholm  goto decode_done;
3ad9861997-01-26Fredrik Hübinette (Hubbe)  }
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_OBJECT:
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  {
ca12fa2008-05-28Henrik Grubbström (Grubba)  int subtype = 0; if (num == 4) { decode_number(subtype, data); }
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
50817d1997-10-07Fredrik Hübinette (Hubbe)  switch(num) { case 0:
a63ecd2011-03-19Martin Stjernholm  apply(decoder_codec (data),"objectof", 1);
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  case 1: {
3d2ae42002-05-02Martin Stjernholm  int fun;
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  /* decode_value_clone_object does not call __INIT, so * we want to do that ourselves... */
fe0b712003-06-12Martin Stjernholm  struct object *o=decode_value_clone_object(Pike_sp-1);
3beae42003-06-02Martin Stjernholm  if (!o) { if (data->pickyness)
2ac4992011-03-09Martin Stjernholm  decode_error (data, NULL, "Failed to decode program for object. Got: %O\n", Pike_sp - 1);
3beae42003-06-02Martin Stjernholm  EDB(1,fprintf(stderr, "%*sDecoded a failed object to <%d>: ",
8d37f12003-06-03Martin Stjernholm  data->depth, "", entry_id.u.integer);
3beae42003-06-02Martin Stjernholm  print_svalue(stderr, Pike_sp-1); fputc('\n', stderr););
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
3beae42003-06-02Martin Stjernholm  pop_n_elems(2); push_undefined(); break; }
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  debug_malloc_touch(o); pop_stack(); push_object(o); if(o->prog) { if(o->prog->flags & PROGRAM_FINISHED) {
92d2d92003-07-30Martin Stjernholm  int lfun = FIND_LFUN(o->prog, LFUN___INIT); if (lfun >= 0) { apply_low(o, lfun, 0); pop_stack(); }
e738b32001-07-16Martin Stjernholm  /* FIXME: Should call LFUN_CREATE here in <= 7.2 * compatibility mode. */
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  }else{ struct unfinished_obj_link *ol=ALLOC_STRUCT(unfinished_obj_link);
478c7d2008-05-21Henrik Grubbström (Grubba)  EDB(2,fprintf(stderr, "%*sDecoded an unfinished object to <%d>: ", data->depth, "", entry_id.u.integer); print_svalue(stderr, Pike_sp-1); fputc('\n', stderr);); add_ref(ol->o = o);
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  ol->next=data->unfinished_objects;
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(ol->decode_arg, PIKE_T_INT, NUMBER_UNDEFINED, integer, 0);
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  data->unfinished_objects=ol;
478c7d2008-05-21Henrik Grubbström (Grubba)  decode_value2(data); assign_svalue(&ol->decode_arg, Pike_sp-1); pop_stack(); break;
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  } } EDB(2,fprintf(stderr, "%*sDecoded an object to <%d>: ",
8d37f12003-06-03Martin Stjernholm  data->depth, "", entry_id.u.integer);
b55a122001-07-10Martin Stjernholm  print_svalue(stderr, Pike_sp-1); fputc('\n', stderr););
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  ref_push_object(o);
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
3d2ae42002-05-02Martin Stjernholm 
a63ecd2011-03-19Martin Stjernholm  fun = find_identifier("decode_object", decoder_codec (data)->prog);
3d2ae42002-05-02Martin Stjernholm  if (fun < 0)
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1,
3beae42003-06-02Martin Stjernholm  "Cannot decode objects without a " "\"decode_object\" function in the codec.\n");
3d2ae42002-05-02Martin Stjernholm  apply_low(data->codec,fun,2);
017b572011-10-28Henrik Grubbström (Grubba)  if ((TYPEOF(Pike_sp[-1]) == T_ARRAY) && o->prog &&
7ec6582008-05-21Henrik Grubbström (Grubba)  ((fun = FIND_LFUN(o->prog, LFUN_CREATE)) != -1)) { /* Call lfun::create(@args). */ INT32 args; Pike_sp--; args = Pike_sp->u.array->size; if (args) { /* Note: Eats reference */ push_array_items(Pike_sp->u.array); } else { free_array(Pike_sp->u.array); } apply_low(o, fun, args); }
50817d1997-10-07Fredrik Hübinette (Hubbe)  pop_stack(); }
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  break;
52bb181999-10-25Fredrik Hübinette (Hubbe)  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();
00cf022003-11-15Martin Stjernholm #if SIZEOF_INT_TYPE > 4 reduce_stack_top_bignum(); #endif
52bb181999-10-25Fredrik Hübinette (Hubbe)  break; }
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  case 3: pop_stack();
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  break;
583ade2000-02-16Per Hedbor 
ca12fa2008-05-28Henrik Grubbström (Grubba)  case 4: /* Subtyped object. */
017b572011-10-28Henrik Grubbström (Grubba)  if ((TYPEOF(Pike_sp[-1]) != T_OBJECT) || SUBTYPEOF(Pike_sp[-1]) ||
ca12fa2008-05-28Henrik Grubbström (Grubba)  !Pike_sp[-1].u.object->prog) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Expected plain object. Got: %O\n", Pike_sp-1);
ca12fa2008-05-28Henrik Grubbström (Grubba)  } if ((subtype < 0) || (subtype >= Pike_sp[-1].u.object->prog->num_inherits)) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Invalid subtype for object: %d (max: %d). " "Object: %O\n", subtype, Pike_sp[-1].u.object->prog->num_inherits, Pike_sp-1);
ca12fa2008-05-28Henrik Grubbström (Grubba)  }
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL_SUBTYPE(Pike_sp[-1], subtype);
ca12fa2008-05-28Henrik Grubbström (Grubba)  break;
50817d1997-10-07Fredrik Hübinette (Hubbe)  default:
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Object coding not compatible: %d\n", num);
50817d1997-10-07Fredrik Hübinette (Hubbe)  break; }
3beae42003-06-02Martin Stjernholm 
017b572011-10-28Henrik Grubbström (Grubba)  if((TYPEOF(Pike_sp[-1]) != T_OBJECT) && data->pickyness) {
b2b4e92008-02-29Henrik Grubbström (Grubba)  if (num != 2) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode object. Got: %O\n", Pike_sp - 1);
017b572011-10-28Henrik Grubbström (Grubba)  } else if (TYPEOF(Pike_sp[-1]) != PIKE_T_INT) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode bignum. Got: %O\n", Pike_sp - 1);
b2b4e92008-02-29Henrik Grubbström (Grubba)  } }
6f7ff82001-07-12Fredrik Hübinette (Hubbe) 
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  }
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_FUNCTION:
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
6cee1e2008-07-31Henrik Grubbström (Grubba)  stack_dup(); /* For diagnostic purposes... */
fe0b712003-06-12Martin Stjernholm 
50817d1997-10-07Fredrik Hübinette (Hubbe)  switch(num) { case 0:
a63ecd2011-03-19Martin Stjernholm  apply(decoder_codec (data),"functionof", 1);
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
583ade2000-02-16Per Hedbor 
e893d12001-07-02Martin Stjernholm  case 1: { struct program *p;
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(Pike_sp[-1]) != T_OBJECT && data->pickyness)
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode function object. Got: %O\n", Pike_sp - 1);
3beae42003-06-02Martin Stjernholm 
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(Pike_sp[-1]) != T_STRING && data->pickyness)
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode function identifier. Got: %O\n", Pike_sp - 1);
3beae42003-06-02Martin Stjernholm 
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-2]) == T_OBJECT && TYPEOF(Pike_sp[-1]) == T_STRING &&
e893d12001-07-02Martin Stjernholm  (p = Pike_sp[-2].u.object->prog)) {
38979d2004-12-20Martin Stjernholm  int f = really_low_find_shared_string_identifier( Pike_sp[-1].u.string,
017b572011-10-28Henrik Grubbström (Grubba)  p->inherits[SUBTYPEOF(Pike_sp[-2])].prog,
6530932008-06-29Martin Nilsson  SEE_PROTECTED|SEE_PRIVATE);
f877222008-02-06Henrik Grubbström (Grubba)  debug_malloc_touch(p);
e893d12001-07-02Martin Stjernholm  if (f >= 0) { struct svalue func; low_object_index_no_free(&func, Pike_sp[-2].u.object, f); #ifdef PIKE_SECURITY /* FIXME: Check access to the function. */ #endif
f877222008-02-06Henrik Grubbström (Grubba)  debug_malloc_touch(p);
e893d12001-07-02Martin Stjernholm  pop_n_elems(2); *Pike_sp++ = func;
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp-1);
e893d12001-07-02Martin Stjernholm  break; }
3beae42003-06-02Martin Stjernholm  else if (data->pickyness) {
f877222008-02-06Henrik Grubbström (Grubba)  debug_malloc_touch(p);
3beae42003-06-02Martin Stjernholm  if (Pike_sp[-1].u.string->size_shift)
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Couldn't find identifier in %O.\n", Pike_sp - 2);
3beae42003-06-02Martin Stjernholm  else
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Couldn't find identifier %s in %O.\n", Pike_sp[-1].u.string->str, Pike_sp - 2);
3beae42003-06-02Martin Stjernholm  }
f877222008-02-06Henrik Grubbström (Grubba)  debug_malloc_touch(p);
5f06241999-04-11Fredrik Hübinette (Hubbe)  }
e893d12001-07-02Martin Stjernholm  pop_stack();
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
e893d12001-07-02Martin Stjernholm  }
583ade2000-02-16Per Hedbor 
50817d1997-10-07Fredrik Hübinette (Hubbe)  default:
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Function coding not compatible: %d\n", num);
50817d1997-10-07Fredrik Hübinette (Hubbe)  break; }
3beae42003-06-02Martin Stjernholm 
017b572011-10-28Henrik Grubbström (Grubba)  if((TYPEOF(Pike_sp[-1]) != T_FUNCTION) && (TYPEOF(Pike_sp[-1]) != T_PROGRAM) &&
6c57792008-07-31Henrik Grubbström (Grubba)  data->pickyness)
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 2, "Failed to decode function. Got: %O\n", Pike_sp - 1);
6cee1e2008-07-31Henrik Grubbström (Grubba)  stack_pop_keep_top();
3beae42003-06-02Martin Stjernholm 
50817d1997-10-07Fredrik Hübinette (Hubbe)  break;
583ade2000-02-16Per Hedbor 
4ba6be1999-12-11Henrik Grubbström (Grubba)  case TAG_PROGRAM:
9182912002-05-10Henrik Grubbström (Grubba)  EDB(3, fprintf(stderr, "%*s TAG_PROGRAM(%d)\n", data->depth, "", num));
05590d1998-04-23Fredrik Hübinette (Hubbe)  switch(num) { case 0:
82d47c1999-11-04Henrik Grubbström (Grubba)  {
96aa1c2002-05-09Martin Stjernholm  struct program *p;
82d47c1999-11-04Henrik Grubbström (Grubba) 
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
a63ecd2011-03-19Martin Stjernholm  apply(decoder_codec (data),"programof", 1);
96aa1c2002-05-09Martin Stjernholm 
fe0b712003-06-12Martin Stjernholm  p = program_from_svalue(Pike_sp-1);
96aa1c2002-05-09Martin Stjernholm 
4901782002-08-06Henrik Grubbström (Grubba)  if (!p) {
3beae42003-06-02Martin Stjernholm  if(data->pickyness)
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode program. Got: %O\n", Pike_sp - 1);
3beae42003-06-02Martin Stjernholm  pop_stack();
4901782002-08-06Henrik Grubbström (Grubba)  push_undefined(); break;
82d47c1999-11-04Henrik Grubbström (Grubba)  }
3beae42003-06-02Martin Stjernholm 
e753f82013-10-12Henrik Grubbström (Grubba)  if ((p->flags & PROGRAM_NEEDS_PARENT)) { EDB(2, fprintf(stderr, "%*sKeeping %s to keep parent pointer.\n", data->depth, "", get_name_of_type(TYPEOF(Pike_sp[-1])))); break; }
3beae42003-06-02Martin Stjernholm  add_ref(p); pop_stack(); push_program(p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  break;
82d47c1999-11-04Henrik Grubbström (Grubba)  }
9182912002-05-10Henrik Grubbström (Grubba) 
3beae42003-06-02Martin Stjernholm  case 1: /* Old-style encoding. */
05590d1998-04-23Fredrik Hübinette (Hubbe)  {
997a002001-11-08Fredrik Hübinette (Hubbe)  int d, in;
f00c362000-08-10Henrik Grubbström (Grubba)  size_t size=0;
997a002001-11-08Fredrik Hübinette (Hubbe)  char *dat=0;
05590d1998-04-23Fredrik Hübinette (Hubbe)  struct program *p;
997a002001-11-08Fredrik Hübinette (Hubbe)  struct object *placeholder=0;
788ca42014-04-28Henrik Grubbström (Grubba)  ONERROR err, err1, err2, err3, err4;
05590d1998-04-23Fredrik Hübinette (Hubbe) 
788ca42014-04-28Henrik Grubbström (Grubba)  lock_pike_compiler(); SET_ONERROR(err, unlock_pike_compiler, 0);
928ad61998-04-27Fredrik Hübinette (Hubbe) 
8d37f12003-06-03Martin Stjernholm  fprintf (stderr, "Warning: Using old-style encoding\n");
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  EDB(2,fprintf(stderr, "%*sDecoding a program to <%d>: ",
8d37f12003-06-03Martin Stjernholm  data->depth, "", entry_id.u.integer); print_svalue(stderr, &entry_id);
b55a122001-07-10Martin Stjernholm  fputc('\n', stderr););
997a002001-11-08Fredrik Hübinette (Hubbe) 
fe0b712003-06-12Martin Stjernholm  SETUP_DECODE_MEMOBJ(T_PROGRAM, program, p, low_allocate_program(),;);
997a002001-11-08Fredrik Hübinette (Hubbe) 
f877222008-02-06Henrik Grubbström (Grubba)  debug_malloc_touch(p);
997a002001-11-08Fredrik Hübinette (Hubbe)  SET_ONERROR(err3, zap_unfinished_program, p);
fe0b712003-06-12Martin Stjernholm 
997a002001-11-08Fredrik Hübinette (Hubbe)  if(data->pass == 1) {
32789f2005-05-31Martin Stjernholm #if TWO_PASS_DECODE_WORKS
997a002001-11-08Fredrik Hübinette (Hubbe)  if(! data->supporter.prog) data->supporter.prog = p;
32789f2005-05-31Martin Stjernholm #endif
997a002001-11-08Fredrik Hübinette (Hubbe)  debug_malloc_touch(p);
8a86892003-06-05Martin Stjernholm  ref_push_program(p);
a63ecd2011-03-19Martin Stjernholm  apply(decoder_codec (data), "__register_new_program", 1);
997a002001-11-08Fredrik Hübinette (Hubbe) 
8a86892003-06-05Martin Stjernholm  /* return a placeholder */
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(Pike_sp[-1]) == T_OBJECT)
8a86892003-06-05Martin Stjernholm  { placeholder=Pike_sp[-1].u.object; if(placeholder->prog != null_program)
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Placeholder object is not " "a __null_program clone.\n");
8a86892003-06-05Martin Stjernholm  dmalloc_touch_svalue(Pike_sp-1); Pike_sp--; }
017b572011-10-28Henrik Grubbström (Grubba)  else if (TYPEOF(Pike_sp[-1]) != T_INT ||
8a86892003-06-05Martin Stjernholm  Pike_sp[-1].u.integer)
2ac4992011-03-09Martin Stjernholm  decode_error (data, NULL, "Expected placeholder object or zero " "from __register_new_program.\n");
8a86892003-06-05Martin Stjernholm  else { pop_stack();
997a002001-11-08Fredrik Hübinette (Hubbe)  } }
fe0b712003-06-12Martin Stjernholm  if(placeholder) SET_ONERROR(err4, zap_placeholder, placeholder);
583ade2000-02-16Per Hedbor 
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
091b322005-05-27Martin Stjernholm  push_compact_version();
c2b4592010-11-22Martin Stjernholm  if(!is_eq(Pike_sp-1,Pike_sp-2) #ifdef ENCODE_DEBUG && !data->debug #endif )
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Cannot decode programs encoded " "with other pike version %O.\n", Pike_sp - 2);
a757011998-05-16Fredrik Hübinette (Hubbe)  pop_n_elems(2);
c2b4592010-11-22Martin Stjernholm #ifdef ENCODE_DEBUG if (!data->debug) #endif data->pickyness++;
3beae42003-06-02Martin Stjernholm 
da652c2001-05-13Fredrik Hübinette (Hubbe)  debug_malloc_touch(p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  decode_number(p->flags,data);
997a002001-11-08Fredrik Hübinette (Hubbe)  if(data->pass == 1) { p->flags &= ~(PROGRAM_FINISHED | PROGRAM_OPTIMIZED | PROGRAM_FIXED | PROGRAM_PASS_1_DONE); p->flags |= PROGRAM_AVOID_CHECK; }
05590d1998-04-23Fredrik Hübinette (Hubbe)  decode_number(p->storage_needed,data);
f3c7152001-04-14Fredrik Hübinette (Hubbe)  decode_number(p->xstorage,data); decode_number(p->parent_info_storage,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);
997a002001-11-08Fredrik Hübinette (Hubbe)  if(data->pass && p->parent) { free_program(p->parent); p->parent=0; }
da652c2001-05-13Fredrik Hübinette (Hubbe)  debug_malloc_touch(p);
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
017b572011-10-28Henrik Grubbström (Grubba)  switch(TYPEOF(Pike_sp[-1]))
f3c7152001-04-14Fredrik Hübinette (Hubbe)  { case T_INT: p->parent=0; break; case T_PROGRAM: p->parent=Pike_sp[-1].u.program; break; case T_FUNCTION: p->parent=program_from_svalue(Pike_sp-1); break; default:
c2b4592010-11-22Martin Stjernholm  if (data->pickyness)
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Program decode failed. Got: %O\n", Pike_sp - 1);
c2b4592010-11-22Martin Stjernholm  p->parent = 0; break;
f3c7152001-04-14Fredrik Hübinette (Hubbe)  }
a72ad72001-07-03Henrik Grubbström (Grubba)  if(p->parent) { add_ref(p->parent); }
f3c7152001-04-14Fredrik Hübinette (Hubbe)  pop_stack();
da652c2001-05-13Fredrik Hübinette (Hubbe)  debug_malloc_touch(p);
7e877a2003-04-02Martin Stjernholm #define FOO(NUMTYPE,TYPE,ARGTYPE,NAME) \ decode_number( p->PIKE_CONCAT(num_,NAME), data);
05590d1998-04-23Fredrik Hübinette (Hubbe) #include "program_areas.h"
583ade2000-02-16Per Hedbor 
997a002001-11-08Fredrik Hübinette (Hubbe)  if(data->pass == 1) {
ced1df2014-03-15Arne Goedeke  int overflow = 0; size_t tmp = 0;
d29d912005-05-31Henrik Grubbström (Grubba) #ifdef PIKE_USE_MACHINE_CODE /* We want our program to be in mexec-allocated memory... */ #define BAR(NUMTYPE,TYPE,ARGTYPE,NAME) #endif /* PIKE_USE_MACHINE_CODE */
ced1df2014-03-15Arne Goedeke #define FOO(NUMTYPE,TYPE,ARGTYPE,NAME) \ if (size) { \ size=DO_ALIGN(size, ALIGNOF(TYPE)); \ overflow |= !size; \ } \ overflow |= DO_SIZE_T_MUL_OVERFLOW(sizeof(p->NAME[0]), p->PIKE_CONCAT(num_,NAME), &tmp)\ | DO_SIZE_T_ADD_OVERFLOW(size, tmp, &size);
05590d1998-04-23Fredrik Hübinette (Hubbe) #include "program_areas.h"
ced1df2014-03-15Arne Goedeke  if (overflow) decode_error(data, NULL, "Program area sizes overflowed.\n");
997a002001-11-08Fredrik Hübinette (Hubbe)  dat=xalloc(size); debug_malloc_touch(dat); MEMSET(dat,0,size); size=0;
d29d912005-05-31Henrik Grubbström (Grubba) #ifdef PIKE_USE_MACHINE_CODE /* We want our program to be in mexec-allocated memory... */ #define BAR(NUMTYPE,TYPE,ARGTYPE,NAME) \
ced1df2014-03-15Arne Goedeke  if (DO_SIZE_T_MUL_OVERFLOW(p->PIKE_CONCAT(num_, NAME), sizeof(p->NAME[0]), &tmp))\ decode_error(data, NULL, "Program area sizes overflowed.\n");\ p->NAME = (TYPE *)mexec_alloc(tmp);
d29d912005-05-31Henrik Grubbström (Grubba) #endif /* PIKE_USE_MACHINE_CODE */
7e877a2003-04-02Martin Stjernholm #define FOO(NUMTYPE,TYPE,ARGTYPE,NAME) \
05590d1998-04-23Fredrik Hübinette (Hubbe)  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"
997a002001-11-08Fredrik Hübinette (Hubbe)  for(e=0;e<p->num_constants;e++)
1ab4ac2008-01-26Martin Stjernholm  mark_free_svalue (&p->constants[e].sval);
05590d1998-04-23Fredrik Hübinette (Hubbe) 
997a002001-11-08Fredrik Hübinette (Hubbe)  debug_malloc_touch(dat); debug_malloc_touch(p); p->total_size=size + sizeof(struct program); p->flags |= PROGRAM_OPTIMIZED; }
05590d1998-04-23Fredrik Hübinette (Hubbe) 
869aed2001-07-23Henrik Grubbström (Grubba)  { INT32 bytecode_method = 0; decode_number(bytecode_method, data); if (bytecode_method != PIKE_BYTECODE_METHOD) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Unsupported byte-code method: %d. Expected %d\n", bytecode_method, PIKE_BYTECODE_METHOD);
869aed2001-07-23Henrik Grubbström (Grubba)  } }
05590d1998-04-23Fredrik Hübinette (Hubbe)  getdata2(p->program, p->num_program);
3dd4172001-07-19Henrik Grubbström (Grubba)  getdata2(p->relocations, p->num_relocations);
697e0a2001-07-20Henrik Grubbström (Grubba)  #ifdef DECODE_PROGRAM
45ab0c2002-05-13Henrik Grubbström (Grubba)  { int byteorder = PIKE_BYTEORDER; /* FIXME: Used by bytecode.h */ DECODE_PROGRAM(p); }
697e0a2001-07-20Henrik Grubbström (Grubba) #endif /* DECODE_PROGRAM */
17f9d52001-08-01Marcus Comstedt  make_program_executable(p);
697e0a2001-07-20Henrik Grubbström (Grubba) 
05590d1998-04-23Fredrik Hübinette (Hubbe)  getdata2(p->linenumbers, p->num_linenumbers);
3beae42003-06-02Martin Stjernholm  /* Now with the linenumber info in place it gets useful to * include the program in error messages. */
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) {
5733ee2002-05-14Henrik Grubbström (Grubba)  char *foo = p->linenumbers + 1; int len = get_small_number(&foo); int shift = *foo; char *fname = ++foo; foo += len << shift;
bb987a1999-10-19Fredrik Hübinette (Hubbe)  get_small_number(&foo); /* pc offset */
5733ee2002-05-14Henrik Grubbström (Grubba)  /* FIXME: Dmalloc doesn't support wide filenames. */ debug_malloc_name(p, fname, get_small_number(&foo));
58ef5e1999-10-19Fredrik Hübinette (Hubbe)  }
aaec3f1999-10-18Fredrik Hübinette (Hubbe) #endif
583ade2000-02-16Per Hedbor 
aaec3f1999-10-18Fredrik Hübinette (Hubbe) 
da652c2001-05-13Fredrik Hübinette (Hubbe)  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;
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Malformed program in decode.\n");
05590d1998-04-23Fredrik Hübinette (Hubbe)  } }
583ade2000-02-16Per Hedbor 
da652c2001-05-13Fredrik Hübinette (Hubbe)  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;
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Malformed program in decode.\n");
05590d1998-04-23Fredrik Hübinette (Hubbe)  } }
583ade2000-02-16Per Hedbor 
da652c2001-05-13Fredrik Hübinette (Hubbe)  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;
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "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);
17c2662001-07-03Fredrik Hübinette (Hubbe) 
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  EDB(3,fprintf(stderr,"IDREF%x < %d: { %d, %d, %d }\n",
17c2662001-07-03Fredrik Hübinette (Hubbe)  p->id,d, p->identifier_references[d].inherit_offset, p->identifier_references[d].identifier_offset,
b55a122001-07-10Martin Stjernholm  p->identifier_references[d].id_flags); );
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
583ade2000-02-16Per Hedbor 
da652c2001-05-13Fredrik Hübinette (Hubbe)  debug_malloc_touch(p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  for(d=0;d<p->num_strings;d++) getdata(p->strings[d]);
da652c2001-05-13Fredrik Hübinette (Hubbe)  debug_malloc_touch(p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  debug_malloc_touch(dat);
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) 
997a002001-11-08Fredrik Hübinette (Hubbe)  if(placeholder && data->pass==1) { if(placeholder->prog != null_program) { debug_malloc_touch(placeholder);
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Placeholder is no longer " "a __null_program clone.\n");
997a002001-11-08Fredrik Hübinette (Hubbe)  }else{ free_program(placeholder->prog); add_ref(placeholder->prog = p); debug_malloc_touch(placeholder); } }
da652c2001-05-13Fredrik Hübinette (Hubbe)  debug_malloc_touch(p);
997a002001-11-08Fredrik Hübinette (Hubbe)  in=p->num_inherits; for(d=0;d<in;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 
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
6c15501999-09-19Fredrik Hübinette (Hubbe)  if(d==0) {
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(Pike_sp[-1]) != T_PROGRAM ||
3beae42003-06-02Martin Stjernholm  Pike_sp[-1].u.program != p) { ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Program decode of self inherit failed. Got: %O\n", Pike_sp - 2);
3beae42003-06-02Martin Stjernholm  }
50ea682003-03-14Henrik Grubbström (Grubba)  sub_ref(p);
6c15501999-09-19Fredrik Hübinette (Hubbe)  }
583ade2000-02-16Per Hedbor 
997a002001-11-08Fredrik Hübinette (Hubbe)  if(data->pass > 1) { if(p->inherits[d].prog) { free_program(p->inherits[d].prog); p->inherits[d].prog=0; } if(p->inherits[d].parent) { free_object(p->inherits[d].parent); p->inherits[d].parent=0; } }
017b572011-10-28Henrik Grubbström (Grubba)  switch(TYPEOF(Pike_sp[-1]))
05590d1998-04-23Fredrik Hübinette (Hubbe)  { case T_PROGRAM:
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  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;
3beae42003-06-02Martin Stjernholm  case T_FUNCTION:
017b572011-10-28Henrik Grubbström (Grubba)  if(SUBTYPEOF(Pike_sp[-1]) != FUNCTION_BUILTIN) { EDB(3, fprintf(stderr,"INHERIT%x = func { %p, %d} \n",p->id,Pike_sp[-1].u.object, SUBTYPEOF(Pike_sp[-1])); );
3beae42003-06-02Martin Stjernholm 
017b572011-10-28Henrik Grubbström (Grubba)  p->inherits[d].parent_identifier = SUBTYPEOF(Pike_sp[-1]);
3beae42003-06-02Martin Stjernholm  p->inherits[d].prog=program_from_svalue(Pike_sp-1); if(!p->inherits[d].prog) { ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Failed to decode " "inherited program. Got: %O\n", Pike_sp - 2);
3beae42003-06-02Martin Stjernholm  } add_ref(p->inherits[d].prog); p->inherits[d].parent=Pike_sp[-1].u.object; Pike_sp--; dmalloc_touch_svalue(Pike_sp); break; } /* Fall through */
05590d1998-04-23Fredrik Hübinette (Hubbe)  default:
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Failed to decode inherited program. Got: %O\n", Pike_sp - 2);
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
583ade2000-02-16Per Hedbor 
997a002001-11-08Fredrik Hübinette (Hubbe)  p->num_inherits=d+1;
11b69f1999-09-17Fredrik Hübinette (Hubbe)  getdata3(p->inherits[d].name);
17c2662001-07-03Fredrik Hübinette (Hubbe) 
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  EDB(3, fprintf(stderr,"INHERIT%x < %d: %d id=%d\n",
17c2662001-07-03Fredrik Hübinette (Hubbe)  p->id,d, p->inherits[d].prog->num_identifiers,
b55a122001-07-10Martin Stjernholm  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);
20d57c2001-07-02Fredrik Hübinette (Hubbe) 
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) 
da652c2001-05-13Fredrik Hübinette (Hubbe)  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);
865d652008-05-16Henrik Grubbström (Grubba)  decode_number(p->identifiers[d].filename_strno, data); decode_number(p->identifiers[d].linenumber, data);
e6dd052007-10-03Henrik Grubbström (Grubba)  if (IDENTIFIER_IS_ALIAS(p->identifiers[d].identifier_flags)) { decode_number(p->identifiers[d].func.ext_ref.depth, data); decode_number(p->identifiers[d].func.ext_ref.id, data); } else if (!IDENTIFIER_IS_C_FUNCTION(p->identifiers[d].identifier_flags))
a72ad72001-07-03Henrik Grubbström (Grubba)  { decode_number(p->identifiers[d].func.offset,data); } else {
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Cannot decode function implemented in C: %S\n", p->identifiers[d].name);
a72ad72001-07-03Henrik Grubbström (Grubba)  }
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
20d57c2001-07-02Fredrik Hübinette (Hubbe) 
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 
da652c2001-05-13Fredrik Hübinette (Hubbe)  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 
da652c2001-05-13Fredrik Hübinette (Hubbe)  debug_malloc_touch(p);
ab9db52003-02-20Henrik Grubbström (Grubba)  fsort_program_identifier_index(p->identifier_index, p->identifier_index + p->num_identifier_index - 1, p);
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  debug_malloc_touch(dat); debug_malloc_touch(p);
997a002001-11-08Fredrik Hübinette (Hubbe) 
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  p->flags |= PROGRAM_PASS_1_DONE | PROGRAM_FIXED; for(d=0;d<p->num_constants;d++) {
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
997a002001-11-08Fredrik Hübinette (Hubbe)  if(data->pass > 1) { assign_svalue(& p->constants[d].sval , Pike_sp -1 ); pop_stack(); }else{
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp-1);
997a002001-11-08Fredrik Hübinette (Hubbe)  p->constants[d].sval=*--Pike_sp; }
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  dmalloc_touch_svalue(Pike_sp);
4ea54f2004-05-29Henrik Grubbström (Grubba)  { struct pike_string *dummy = NULL; getdata3(dummy /*p->constants[d].name*/); if (dummy) free_string(dummy); }
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  }
997a002001-11-08Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG { int q; for(q=0;q<p->num_inherits;q++) if(!p->inherits[q].prog)
5aad932002-08-15Marcus Comstedt  Pike_fatal("FOOBAR!@!!!\n");
997a002001-11-08Fredrik Hübinette (Hubbe)  } #endif
6f7ff82001-07-12Fredrik Hübinette (Hubbe) 
997a002001-11-08Fredrik Hübinette (Hubbe)  if(placeholder && data->pass == 1) {
3beae42003-06-02Martin Stjernholm  if(placeholder->storage)
997a002001-11-08Fredrik Hübinette (Hubbe)  {
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Placeholder already has storage!\n");
997a002001-11-08Fredrik Hübinette (Hubbe)  } else { placeholder->storage=p->storage_needed ?
b81a1d2014-04-27Martin Nilsson  xcalloc(p->storage_needed, 1) : NULL;
997a002001-11-08Fredrik Hübinette (Hubbe)  call_c_initializers(placeholder); } }
c2b4592010-11-22Martin Stjernholm  #ifdef ENCODE_DEBUG if (!data->debug) #endif data->pickyness--;
997a002001-11-08Fredrik Hübinette (Hubbe) 
fe0b712003-06-12Martin Stjernholm  if(placeholder) { free_object(placeholder); UNSET_ONERROR(err4); }
da652c2001-05-13Fredrik Hübinette (Hubbe)  UNSET_ONERROR(err3);
20d57c2001-07-02Fredrik Hübinette (Hubbe) 
05590d1998-04-23Fredrik Hübinette (Hubbe)  ref_push_program(p);
928ad61998-04-27Fredrik Hübinette (Hubbe) 
32789f2005-05-31Martin Stjernholm  if(!(p->flags & PROGRAM_FINISHED) #if TWO_PASS_DECODE_WORKS && !data->supporter.depends_on #endif )
20d57c2001-07-02Fredrik Hübinette (Hubbe)  {
997a002001-11-08Fredrik Hübinette (Hubbe)  /* Logic for the PROGRAM_FINISHED flag: * The purpose of this code is to make sure that the PROGRAM_FINISHED
d2361e2003-06-30Martin Stjernholm  * flag is not set on the program until all inherited programs also
997a002001-11-08Fredrik Hübinette (Hubbe)  * have that flag. -Hubbe
20d57c2001-07-02Fredrik Hübinette (Hubbe)  */
997a002001-11-08Fredrik Hübinette (Hubbe)  for(d=1;d<p->num_inherits;d++) if(! (p->inherits[d].prog->flags & PROGRAM_FINISHED)) break; if(d == p->num_inherits)
20d57c2001-07-02Fredrik Hübinette (Hubbe)  {
997a002001-11-08Fredrik Hübinette (Hubbe)  p->flags &=~ PROGRAM_AVOID_CHECK; p->flags |= PROGRAM_FINISHED;
6f7ff82001-07-12Fredrik Hübinette (Hubbe) 
997a002001-11-08Fredrik Hübinette (Hubbe)  if (placeholder) { if(!init_placeholder(placeholder)) placeholder=0; } /* Go through the linked list of unfinished programs * to see what programs are now finished.
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  */
20d57c2001-07-02Fredrik Hübinette (Hubbe)  {
997a002001-11-08Fredrik Hübinette (Hubbe)  struct unfinished_prog_link *l, **ptr; #ifdef PIKE_DEBUG check_program(p); #endif /* PIKE_DEBUG */
20d57c2001-07-02Fredrik Hübinette (Hubbe) 
997a002001-11-08Fredrik Hübinette (Hubbe)  /* It is possible that we need to restart loop * in some cases... /Hubbe */ for(ptr= &data->unfinished_programs ; (l=*ptr);)
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  {
997a002001-11-08Fredrik Hübinette (Hubbe)  struct program *pp=l->prog; for(d=1;d<pp->num_inherits;d++) if(! (pp->inherits[d].prog->flags & PROGRAM_FINISHED)) break;
6f7ff82001-07-12Fredrik Hübinette (Hubbe) 
997a002001-11-08Fredrik Hübinette (Hubbe)  if(d == pp->num_inherits) {
f8214b2003-02-24Martin Stjernholm  fsort_program_identifier_index(pp->identifier_index, pp->identifier_index + pp->num_identifier_index - 1, pp);
997a002001-11-08Fredrik Hübinette (Hubbe)  pp->flags &=~ PROGRAM_AVOID_CHECK; pp->flags |= PROGRAM_FINISHED;
20d57c2001-07-02Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
997a002001-11-08Fredrik Hübinette (Hubbe)  check_program(pp);
20d57c2001-07-02Fredrik Hübinette (Hubbe) #endif /* PIKE_DEBUG */
997a002001-11-08Fredrik Hübinette (Hubbe)  *ptr = l->next;
26bb952014-04-27Martin Nilsson  free(l);
997a002001-11-08Fredrik Hübinette (Hubbe)  }else{ ptr=&l->next; }
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  } }
997a002001-11-08Fredrik Hübinette (Hubbe)  /* Go through the linked list of unfinished objects * to see what objects are now finished. */
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  {
7ec6582008-05-21Henrik Grubbström (Grubba)  int decode_fun = -1;
997a002001-11-08Fredrik Hübinette (Hubbe)  struct unfinished_obj_link *l, **ptr;
478c7d2008-05-21Henrik Grubbström (Grubba)  if (data->unfinished_objects) {
a63ecd2011-03-19Martin Stjernholm  decode_fun = find_identifier("decode_object", decoder_codec (data)->prog);
7ec6582008-05-21Henrik Grubbström (Grubba)  if (decode_fun < 0)
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1,
478c7d2008-05-21Henrik Grubbström (Grubba)  "Cannot decode objects without a " "\"decode_object\" function in the codec.\n"); }
997a002001-11-08Fredrik Hübinette (Hubbe)  for(ptr= &data->unfinished_objects ; (l=*ptr);)
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  {
7ec6582008-05-21Henrik Grubbström (Grubba)  int fun;
997a002001-11-08Fredrik Hübinette (Hubbe)  struct object *o=l->o; if(o->prog)
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  {
997a002001-11-08Fredrik Hübinette (Hubbe)  if(o->prog->flags & PROGRAM_FINISHED) { apply_lfun(o, LFUN___INIT, 0); pop_stack(); /* FIXME: Should call LFUN_CREATE here in <= 7.2 * compatibility mode. */ }else{ ptr=&l->next; continue; }
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  }
478c7d2008-05-21Henrik Grubbström (Grubba)  /* Note: We steal the references from l. */ push_object(o); *(Pike_sp++) = l->decode_arg;
997a002001-11-08Fredrik Hübinette (Hubbe)  *ptr = l->next;
26bb952014-04-27Martin Nilsson  free(l);
478c7d2008-05-21Henrik Grubbström (Grubba)  /* Let the codec do it's job... */
a63ecd2011-03-19Martin Stjernholm  apply_low(decoder_codec (data), decode_fun, 2);
017b572011-10-28Henrik Grubbström (Grubba)  if ((TYPEOF(Pike_sp[-1]) == T_ARRAY) &&
eb291b2013-02-16Henrik Grubbström (Grubba)  o->prog &&
7ec6582008-05-21Henrik Grubbström (Grubba)  ((fun = FIND_LFUN(o->prog, LFUN_CREATE)) != -1)) { /* Call lfun::create(@args). */ INT32 args; Pike_sp--; args = Pike_sp->u.array->size; if (args) { /* Note: Eats reference to the array. */ push_array_items(Pike_sp->u.array); } else { free_array(Pike_sp->u.array); } apply_low(o, fun, args); }
478c7d2008-05-21Henrik Grubbström (Grubba)  pop_stack();
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  }
20d57c2001-07-02Fredrik Hübinette (Hubbe)  }
997a002001-11-08Fredrik Hübinette (Hubbe)  }else{ struct unfinished_prog_link *l; l=ALLOC_STRUCT(unfinished_prog_link); l->prog=p; l->next=data->unfinished_programs; data->unfinished_programs=l;
20d57c2001-07-02Fredrik Hübinette (Hubbe)  } }
788ca42014-04-28Henrik Grubbström (Grubba)  CALL_AND_UNSET_ONERROR(err);
8d37f12003-06-03Martin Stjernholm  goto decode_done;
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
51717a2001-04-09Fredrik Hübinette (Hubbe)  case 2:
fe0b712003-06-12Martin Stjernholm  decode_value2(data); decode_value2(data);
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(Pike_sp[-2]) == T_INT)
51717a2001-04-09Fredrik Hübinette (Hubbe)  { pop_stack(); }else{ f_arrow(2); }
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(Pike_sp[-1]) != T_PROGRAM && data->pickyness)
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode program. Got: %O\n", Pike_sp - 1);
51717a2001-04-09Fredrik Hübinette (Hubbe)  break;
f8d8f42001-07-01Henrik Grubbström (Grubba)  case 3:
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
017b572011-10-28Henrik Grubbström (Grubba)  if ((TYPEOF(Pike_sp[-1]) == T_INT) &&
f8d8f42001-07-01Henrik Grubbström (Grubba)  (Pike_sp[-1].u.integer < PROG_DYNAMIC_ID_START) && (Pike_sp[-1].u.integer > 0)) { struct program *p = id_to_program(Pike_sp[-1].u.integer); if (!p) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to get program from ID %O.\n", Pike_sp - 1);
f8d8f42001-07-01Henrik Grubbström (Grubba)  } pop_stack();
b56df22001-07-01Henrik Grubbström (Grubba)  ref_push_program(p);
f8d8f42001-07-01Henrik Grubbström (Grubba)  } else {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode program by ID. " "Expected integer, got: %O\n", Pike_sp - 1);
f8d8f42001-07-01Henrik Grubbström (Grubba)  } break;
fe0b712003-06-12Martin Stjernholm  case 5: { /* Forward reference for new-style encoding. */ struct program *p = low_allocate_program(); push_program (p);
8d37f12003-06-03Martin Stjernholm  EDB(2, fprintf (stderr, "%*sInited an embryo for a delay encoded program " "to <%d>: ", data->depth, "", entry_id.u.integer); print_svalue (stderr, Pike_sp - 1); fputc ('\n', stderr););
fe0b712003-06-12Martin Stjernholm 
0efe6b2008-05-26Henrik Grubbström (Grubba)  data->delay_counter++;
fe0b712003-06-12Martin Stjernholm #if 0 /* Is this necessary? In that case, how do we pass an * adequate context to __register_new_program so that it * knows which program is being decoded? */ ref_push_program (p);
a63ecd2011-03-19Martin Stjernholm  apply (decoder_codec (data), "__register_new_program", 1);
fe0b712003-06-12Martin Stjernholm  /* Returns a placeholder. */
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) == T_OBJECT) {
fe0b712003-06-12Martin Stjernholm  if (Pike_sp[-1].u.object->prog != null_program)
2ac4992011-03-09Martin Stjernholm  decode_error (data, NULL, "Placeholder object is not " "a null_program clone.\n");
fe0b712003-06-12Martin Stjernholm  }
017b572011-10-28Henrik Grubbström (Grubba)  else if (TYPEOF(Pike_sp[-1]) != T_INT ||
fe0b712003-06-12Martin Stjernholm  Pike_sp[-1].u.integer)
2ac4992011-03-09Martin Stjernholm  decode_error (data, NULL, "Expected placeholder object or zero " "from __register_new_program.\n");
fe0b712003-06-12Martin Stjernholm  pop_stack(); #endif
8d37f12003-06-03Martin Stjernholm  break;
fe0b712003-06-12Martin Stjernholm  }
8d37f12003-06-03Martin Stjernholm 
3beae42003-06-02Martin Stjernholm  case 4: /* New-style encoding. */
9182912002-05-10Henrik Grubbström (Grubba)  { struct program *p; ONERROR err;
2479e92003-08-05Henrik Grubbström (Grubba)  ONERROR err2;
9182912002-05-10Henrik Grubbström (Grubba)  int byteorder; int bytecode_method; int entry_type; INT16 id_flags; INT16 p_flags;
e021fe2008-04-14Henrik Grubbström (Grubba)  ptrdiff_t old_pragmas; struct compilation *c;
865d652008-05-16Henrik Grubbström (Grubba)  struct pike_string *save_current_file;
ec414a2008-05-26Henrik Grubbström (Grubba)  struct object *placeholder = NULL;
ef24a82012-01-12Henrik Grubbström (Grubba)  INT_TYPE save_current_line;
7e877a2003-04-02Martin Stjernholm #define FOO(NUMTYPE,Y,ARGTYPE,NAME) \
9182912002-05-10Henrik Grubbström (Grubba)  NUMTYPE PIKE_CONCAT(local_num_, NAME) = 0; #include "program_areas.h" #ifdef ENCODE_DEBUG data->depth += 2; #endif /* Decode byte-order. */ decode_number(byteorder, data); EDB(4,
8d37f12003-06-03Martin Stjernholm  fprintf(stderr, "%*sbyte order:%d\n",
9182912002-05-10Henrik Grubbström (Grubba)  data->depth, "", byteorder)); if ((byteorder != PIKE_BYTEORDER) #if (PIKE_BYTEORDER == 1234) && (byteorder != 4321) #else #if (PIKE_BYTEORDER == 4321) && (byteorder != 1234) #endif #endif ) {
2ac4992011-03-09Martin Stjernholm  decode_error (data, NULL, "Unsupported byte-order. " "Native:%d Encoded:%d\n", PIKE_BYTEORDER, byteorder);
9182912002-05-10Henrik Grubbström (Grubba)  } /* Decode flags. */ decode_number(p_flags,data); p_flags &= ~(PROGRAM_FINISHED | PROGRAM_OPTIMIZED | PROGRAM_FIXED | PROGRAM_PASS_1_DONE); p_flags |= PROGRAM_AVOID_CHECK;
8d37f12003-06-03Martin Stjernholm  if (delayed_enc_val) { EDB(2,fprintf(stderr, "%*sdecoding a delay encoded program: ", data->depth, ""); print_svalue(stderr, delayed_enc_val); fputc('\n', stderr););
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*delayed_enc_val) != T_PROGRAM ||
8d37f12003-06-03Martin Stjernholm  delayed_enc_val->u.program->flags != PROGRAM_VIRGIN) {
2ac4992011-03-09Martin Stjernholm  decode_error (data, NULL, "Didn't get program embryo " "for delay encoded program <%O>: %O\n", &entry_id, delayed_enc_val);
8d37f12003-06-03Martin Stjernholm  }
6111812003-06-05Martin Stjernholm  /* No new ref here; low_start_new_program will add one for
fe0b712003-06-12Martin Stjernholm  * Pike_compiler->new_program and we want ride on that one * just like when it's created there. */
6111812003-06-05Martin Stjernholm  p = delayed_enc_val->u.program;
f877222008-02-06Henrik Grubbström (Grubba)  debug_malloc_touch(p);
8d37f12003-06-03Martin Stjernholm  } else p = NULL;
e021fe2008-04-14Henrik Grubbström (Grubba)  enter_compiler(NULL, 0); c = THIS_COMPILATION;
2479e92003-08-05Henrik Grubbström (Grubba)  /* We don't want to be affected by #pragma save_parent or * __pragma_save_parent__. */
e021fe2008-04-14Henrik Grubbström (Grubba)  old_pragmas = c->lex.pragmas; c->lex.pragmas = (old_pragmas & ~ID_SAVE_PARENT)|ID_DONT_SAVE_PARENT;
2479e92003-08-05Henrik Grubbström (Grubba) 
9182912002-05-10Henrik Grubbström (Grubba)  /* Start the new program. */
8d37f12003-06-03Martin Stjernholm  low_start_new_program(p, 1, NULL, 0, NULL);
9182912002-05-10Henrik Grubbström (Grubba)  p = Pike_compiler->new_program;
32789f2005-05-31Martin Stjernholm #if TWO_PASS_DECODE_WORKS if(! data->supporter.prog) data->supporter.prog = p; #endif
9182912002-05-10Henrik Grubbström (Grubba)  p->flags = p_flags; /* Kludge to get end_first_pass() to free the program. */ Pike_compiler->num_parse_error++;
8853882008-04-26Henrik Grubbström (Grubba)  SET_ONERROR(err, cleanup_new_program_decode, NULL);
9182912002-05-10Henrik Grubbström (Grubba) 
ec414a2008-05-26Henrik Grubbström (Grubba)  { int fun = find_identifier("__register_new_program",
a63ecd2011-03-19Martin Stjernholm  decoder_codec (data)->prog);
6f01232008-05-26Henrik Grubbström (Grubba) 
ec414a2008-05-26Henrik Grubbström (Grubba)  if (fun >= 0) { ref_push_program(p); apply_low(data->codec, fun, 1);
6f01232008-05-26Henrik Grubbström (Grubba) 
ec414a2008-05-26Henrik Grubbström (Grubba)  /* Returned a placeholder */
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(Pike_sp[-1]) == T_OBJECT)
ec414a2008-05-26Henrik Grubbström (Grubba)  { add_ref(c->placeholder=Pike_sp[-1].u.object); if(c->placeholder->prog != null_program) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Placeholder object is not " "a __null_program clone.\n");
ec414a2008-05-26Henrik Grubbström (Grubba)  }
017b572011-10-28Henrik Grubbström (Grubba)  } else if (TYPEOF(Pike_sp[-1]) != T_INT ||
ec414a2008-05-26Henrik Grubbström (Grubba)  Pike_sp[-1].u.integer) {
2ac4992011-03-09Martin Stjernholm  decode_error (data, NULL, "Expected placeholder object or zero " "from __register_new_program.\n");
ec414a2008-05-26Henrik Grubbström (Grubba)  } pop_stack();
6f01232008-05-26Henrik Grubbström (Grubba)  } }
9182912002-05-10Henrik Grubbström (Grubba) 
e614052008-05-17Henrik Grubbström (Grubba)  copy_shared_string(save_current_file, c->lex.current_file); save_current_line = c->lex.current_line; SET_ONERROR(err2, restore_current_file, save_current_file);
8d37f12003-06-03Martin Stjernholm  if (!delayed_enc_val) { struct svalue prog;
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(prog, T_PROGRAM, 0, program, p);
8d37f12003-06-03Martin Stjernholm  EDB(2,fprintf(stderr, "%*sDecoding a program to <%d>: ", data->depth, "", entry_id.u.integer); print_svalue(stderr, &prog); fputc('\n', stderr);); mapping_insert(data->decoded, &entry_id, &prog);
f877222008-02-06Henrik Grubbström (Grubba)  debug_malloc_touch(p);
0efe6b2008-05-26Henrik Grubbström (Grubba)  } else { data->delay_counter--;
8d37f12003-06-03Martin Stjernholm  }
9182912002-05-10Henrik Grubbström (Grubba)  debug_malloc_touch(p); /* Check the version. */
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
091b322005-05-27Martin Stjernholm  push_compact_version();
c2b4592010-11-22Martin Stjernholm  if(!is_eq(Pike_sp-1,Pike_sp-2) #ifdef ENCODE_DEBUG && !data->debug #endif )
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Cannot decode programs encoded with " "other pike version %O.\n", Pike_sp - 2);
9182912002-05-10Henrik Grubbström (Grubba)  pop_n_elems(2); debug_malloc_touch(p);
c2b4592010-11-22Martin Stjernholm #ifdef ENCODE_DEBUG if (!data->debug) #endif data->pickyness++;
f9b1622003-06-01Martin Stjernholm 
9182912002-05-10Henrik Grubbström (Grubba)  /* parent */
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) == T_PROGRAM) {
9182912002-05-10Henrik Grubbström (Grubba)  p->parent = Pike_sp[-1].u.program;
f877222008-02-06Henrik Grubbström (Grubba)  debug_malloc_touch(p->parent);
017b572011-10-28Henrik Grubbström (Grubba)  } else if ((TYPEOF(Pike_sp[-1]) == T_INT) &&
9182912002-05-10Henrik Grubbström (Grubba)  (!Pike_sp[-1].u.integer)) { p->parent = NULL; } else {
2ac4992011-03-09Martin Stjernholm  decode_error (data, NULL, "Bad type for parent program (%s).\n",
017b572011-10-28Henrik Grubbström (Grubba)  get_name_of_type(TYPEOF(Pike_sp[-1])));
9182912002-05-10Henrik Grubbström (Grubba)  }
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp-1);
9182912002-05-10Henrik Grubbström (Grubba)  Pike_sp--; /* Decode lengths. */
7e877a2003-04-02Martin Stjernholm #define FOO(NUMTYPE,TYPE,ARGTYPE,NAME) \ decode_number(PIKE_CONCAT(local_num_, NAME), data);
9182912002-05-10Henrik Grubbström (Grubba) #include "program_areas.h" /* Byte-code method */ decode_number(bytecode_method, data);
82723d2003-11-25Henrik Grubbström (Grubba)  if (bytecode_method == PIKE_BYTECODE_PORTABLE) { } else if (bytecode_method != PIKE_BYTECODE_METHOD) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Unsupported byte-code method: %d\n", bytecode_method);
82723d2003-11-25Henrik Grubbström (Grubba)  } else {
9182912002-05-10Henrik Grubbström (Grubba) 
979d282004-05-12Henrik Grubbström (Grubba) #ifdef PIKE_PORTABLE_BYTECODE fprintf(stderr, "Warning: Decoding non-portable bytecode.\n"); #endif /* PIKE_PORTABLE_BYTECODE */
6b06d82003-11-17Henrik Grubbström (Grubba) #ifdef PIKE_USE_MACHINE_CODE
82723d2003-11-25Henrik Grubbström (Grubba)  { size_t csum; /* Check the checksum of the instrs array. */ decode_number(csum, data); if (csum != instrs_checksum) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Bad instruction checksum: %d (expected %d)\n", csum, instrs_checksum);
82723d2003-11-25Henrik Grubbström (Grubba)  } }
6b06d82003-11-17Henrik Grubbström (Grubba) #endif /* PIKE_USE_MACHINE_CODE */
82723d2003-11-25Henrik Grubbström (Grubba)  /* Decode program */
ced1df2014-03-15Arne Goedeke  if (SIZE_T_MUL_OVERFLOW(local_num_program, sizeof(PIKE_OPCODE_T)) || local_num_program * sizeof(PIKE_OPCODE_T) >= (size_t)(data->len - data->ptr)) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode program (string too short).\n");
82723d2003-11-25Henrik Grubbström (Grubba)  }
65a6f22009-08-17Henrik Grubbström (Grubba)  low_add_many_to_program(Pike_compiler,
9c6b3d2009-08-17Henrik Grubbström (Grubba)  (PIKE_OPCODE_T *)(data->data + data->ptr),
65a6f22009-08-17Henrik Grubbström (Grubba)  local_num_program);
9c6b3d2009-08-17Henrik Grubbström (Grubba)  data->ptr += local_num_program * sizeof(PIKE_OPCODE_T);
9182912002-05-10Henrik Grubbström (Grubba) 
82723d2003-11-25Henrik Grubbström (Grubba)  /* Decode relocations */ for (e=0; e<(int)local_num_relocations; e++) { size_t reloc; decode_number(reloc, data);
2d76f22005-05-20Martin Stjernholm  CHECK_RELOC(reloc, (size_t) local_num_program);
82723d2003-11-25Henrik Grubbström (Grubba)  add_to_relocations(reloc); }
9182912002-05-10Henrik Grubbström (Grubba) 
82723d2003-11-25Henrik Grubbström (Grubba)  /* Perform relocation. */
9182912002-05-10Henrik Grubbström (Grubba) #ifdef DECODE_PROGRAM
82723d2003-11-25Henrik Grubbström (Grubba)  DECODE_PROGRAM(p);
9182912002-05-10Henrik Grubbström (Grubba) #endif /* DECODE_PROGRAM */
82723d2003-11-25Henrik Grubbström (Grubba)  make_program_executable(p);
9182912002-05-10Henrik Grubbström (Grubba) 
82723d2003-11-25Henrik Grubbström (Grubba)  /* Decode linenumbers */
ae558d2014-03-12Arne Goedeke  if (local_num_linenumbers >= (size_t)(data->len - data->ptr)) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to decode linenumbers " "(string too short).\n");
82723d2003-11-25Henrik Grubbström (Grubba)  } for (e=0; e<(int)local_num_linenumbers; e++) { char lineno_info; lineno_info = *(data->data + data->ptr++); add_to_linenumbers(lineno_info); }
9182912002-05-10Henrik Grubbström (Grubba) 
82723d2003-11-25Henrik Grubbström (Grubba)  /* Now with the linenumber info in place it gets useful to * include the program in error messages. */
3beae42003-06-02Martin Stjernholm 
82723d2003-11-25Henrik Grubbström (Grubba)  EDB(2, fprintf(stderr, "%*sThe program is: ", data->depth, ""); push_program (p); print_svalue (stderr, --Pike_sp); fputc('\n', stderr)); }
8d37f12003-06-03Martin Stjernholm 
9182912002-05-10Henrik Grubbström (Grubba)  /* identifier_index & variable_index are created by * fixate_program() and optimize_program(). */ /* Decode strings */ for (e=0; e<local_num_strings; e++) {
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) != T_STRING) {
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Nonstrings in string table: %O\n", Pike_sp - 2);
9182912002-05-10Henrik Grubbström (Grubba)  } add_to_strings(Pike_sp[-1].u.string);
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp-1);
9182912002-05-10Henrik Grubbström (Grubba)  Pike_sp--; }
82723d2003-11-25Henrik Grubbström (Grubba)  /* First pass constants.
9182912002-05-10Henrik Grubbström (Grubba)  * * These will be replaced later on. */ { struct program_constant constant;
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(constant.sval, T_INT, NUMBER_UNDEFINED, integer, 0);
4ea54f2004-05-29Henrik Grubbström (Grubba)  constant.offset = -1;
9182912002-05-10Henrik Grubbström (Grubba)  for(e=0;e<local_num_constants;e++) { add_to_constants(constant); } } /* Decode identifier_references, inherits and identifiers. */ decode_number(entry_type, data); EDB(4, fprintf(stderr, "%*sDecoding identifier references.\n", data->depth, "")); #ifdef ENCODE_DEBUG data->depth+=2; #endif
aeed272004-05-19Henrik Grubbström (Grubba)  while ((entry_type == ID_ENTRY_EFUN_CONSTANT) || (entry_type == ID_ENTRY_TYPE_CONSTANT)) {
b262632003-11-25Henrik Grubbström (Grubba)  INT32 efun_no;
82723d2003-11-25Henrik Grubbström (Grubba)  struct program_constant *constant;
b262632003-11-25Henrik Grubbström (Grubba)  decode_number(efun_no, data); EDB(2,
aeed272004-05-19Henrik Grubbström (Grubba)  fprintf(stderr, "%*sDecoding efun/type constant #%d.\n",
b262632003-11-25Henrik Grubbström (Grubba)  data->depth, "", efun_no)); if ((efun_no < 0) || (efun_no >= local_num_constants)) {
82723d2003-11-25Henrik Grubbström (Grubba)  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1,
aeed272004-05-19Henrik Grubbström (Grubba)  "Bad efun/type number: %d (expected 0 - %d).\n",
b262632003-11-25Henrik Grubbström (Grubba)  efun_no, local_num_constants-1);
82723d2003-11-25Henrik Grubbström (Grubba)  }
b262632003-11-25Henrik Grubbström (Grubba)  constant = p->constants+efun_no;
82723d2003-11-25Henrik Grubbström (Grubba)  /* value */ decode_value2(data);
aeed272004-05-19Henrik Grubbström (Grubba)  switch(entry_type) { case ID_ENTRY_EFUN_CONSTANT:
017b572011-10-28Henrik Grubbström (Grubba)  if (((TYPEOF(Pike_sp[-1]) != T_FUNCTION) || (SUBTYPEOF(Pike_sp[-1]) != FUNCTION_BUILTIN)) &&
c2b4592010-11-22Martin Stjernholm  data->pickyness) {
aeed272004-05-19Henrik Grubbström (Grubba)  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Expected efun constant: %O\n", Pike_sp - 2);
aeed272004-05-19Henrik Grubbström (Grubba)  } break; case ID_ENTRY_TYPE_CONSTANT:
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) != T_TYPE && data->pickyness) {
aeed272004-05-19Henrik Grubbström (Grubba)  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Expected type constant: %O\n", Pike_sp - 2);
aeed272004-05-19Henrik Grubbström (Grubba)  } break; default:
c2b4592010-11-22Martin Stjernholm  if (data->pickyness)
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Internal error: " "Unsupported early constant (%d).\n", entry_type);
aeed272004-05-19Henrik Grubbström (Grubba)  break;
82723d2003-11-25Henrik Grubbström (Grubba)  } /* name */ decode_value2(data);
4ea54f2004-05-29Henrik Grubbström (Grubba) #if 0
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) == T_STRING) {
82723d2003-11-25Henrik Grubbström (Grubba)  constant->name = Pike_sp[-1].u.string;
017b572011-10-28Henrik Grubbström (Grubba)  } else if ((TYPEOF(Pike_sp[-1]) == T_INT) &&
82723d2003-11-25Henrik Grubbström (Grubba)  !Pike_sp[-1].u.integer) { constant->name = NULL; } else { ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Name of constant is not a string: %O\n", Pike_sp - 2);
82723d2003-11-25Henrik Grubbström (Grubba)  } constant->sval = Pike_sp[-2]; dmalloc_touch_svalue(Pike_sp-1); dmalloc_touch_svalue(Pike_sp-2); Pike_sp -= 2;
4ea54f2004-05-29Henrik Grubbström (Grubba) #else /* !0 */ constant->offset = -1; pop_stack(); constant->sval = Pike_sp[-1]; dmalloc_touch_svalue(Pike_sp-1); Pike_sp -= 1; #endif /* 0 */
82723d2003-11-25Henrik Grubbström (Grubba)  decode_number(entry_type, data); }
dc672b2008-02-08Henrik Grubbström (Grubba) 
9182912002-05-10Henrik Grubbström (Grubba)  while (entry_type != ID_ENTRY_EOT) { decode_number(id_flags, data);
865d652008-05-16Henrik Grubbström (Grubba)  if ((entry_type != ID_ENTRY_RAW) && (entry_type != ID_ENTRY_INHERIT)) { /* Common identifier fields. */ unsigned INT32 filename_strno; /* name */ decode_value2(data);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) != T_STRING) {
865d652008-05-16Henrik Grubbström (Grubba)  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Bad identifier name (not a string): %O\n", Pike_sp - 2);
865d652008-05-16Henrik Grubbström (Grubba)  } /* type */ decode_value2(data);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) != T_TYPE) {
865d652008-05-16Henrik Grubbström (Grubba)  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Bad identifier type (not a type): %O\n", Pike_sp - 2);
865d652008-05-16Henrik Grubbström (Grubba)  } /* filename */ decode_number(filename_strno, data); if (filename_strno >= p->num_strings) { ref_push_program(p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL,
865d652008-05-16Henrik Grubbström (Grubba)  "String number out of range: %ld >= %ld", (long)filename_strno, (long)p->num_strings); } free_string(c->lex.current_file); copy_shared_string(c->lex.current_file, p->strings[filename_strno]); /* linenumber */ decode_number(c->lex.current_line, data); /* Identifier name and type on the pike stack. * Definition location in c->lex. */ }
9182912002-05-10Henrik Grubbström (Grubba)  switch(entry_type) { case ID_ENTRY_RAW: { int no; int ref_no; struct reference ref; /* id_flags */ ref.id_flags = id_flags; /* inherit_offset */ decode_number(ref.inherit_offset, data); /* identifier_offset */ /* Actually the id ref number from the inherited program */ decode_number(ref_no, data);
db7fe62014-03-12Arne Goedeke  if (ref.inherit_offset >= p->num_inherits) decode_error(data, NULL, "Inherit offset out of range %u vs %u.\n", ref.inherit_offset, p->num_inherits); if (ref_no < 0 || ref_no >= p->inherits[ref.inherit_offset].prog->num_identifier_references) decode_error(data, NULL, "Identifier reference out of range %u vs %u.\n", ref_no, p->inherits[ref.inherit_offset].prog->num_identifier_references);
9182912002-05-10Henrik Grubbström (Grubba)  ref.identifier_offset = p->inherits[ref.inherit_offset].prog-> identifier_references[ref_no].identifier_offset;
3cb6de2010-11-25Henrik Grubbström (Grubba)  ref.run_time_type = PIKE_T_UNKNOWN; ref.func.offset = 0;
9182912002-05-10Henrik Grubbström (Grubba)  /* Expected identifier reference number */ decode_number(no, data);
b44fab2014-04-15Arne Goedeke  if (no < 0 || no > p->num_identifier_references) {
9182912002-05-10Henrik Grubbström (Grubba)  EDB (3, dump_program_tables (p, data->depth));
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Bad identifier reference offset: %d != %d\n", no,
3beae42003-06-02Martin Stjernholm  Pike_compiler->new_program-> num_identifier_references);
9182912002-05-10Henrik Grubbström (Grubba)  } else if (no == p->num_identifier_references) { add_to_identifier_references(ref); } else { p->identifier_references[no] = ref; } } break; case ID_ENTRY_VARIABLE: {
8a86892003-06-05Martin Stjernholm  int no, n;
9182912002-05-10Henrik Grubbström (Grubba)  /* Expected identifier offset */ decode_number(no, data); EDB(5, fprintf(stderr, "%*sdefine_variable(\"%s\", X, 0x%04x)\n", data->depth, "", Pike_sp[-2].u.string->str, id_flags)); /* Alters * * storage, variable_index, identifiers and * identifier_references */
8a86892003-06-05Martin Stjernholm  n = define_variable(Pike_sp[-2].u.string, Pike_sp[-1].u.type, id_flags); if (no != n) {
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Bad variable identifier offset " "(got %d, expected %d).\n", n, no);
9182912002-05-10Henrik Grubbström (Grubba)  } pop_n_elems(2); } break; case ID_ENTRY_FUNCTION: { union idptr func; unsigned INT8 func_flags; unsigned INT16 opt_flags; int no; int n; /* func_flags (aka identifier_flags) */ decode_number(func_flags, data); /* func */ decode_number(func.offset, data);
82723d2003-11-25Henrik Grubbström (Grubba)  if (bytecode_method == PIKE_BYTECODE_PORTABLE && func.offset != -1) {
f26a512003-12-11Henrik Grubbström (Grubba) #ifdef ENCODE_DEBUG int old_a_flag; #endif
b262632003-11-25Henrik Grubbström (Grubba)  EDB(2,
f26a512003-12-11Henrik Grubbström (Grubba)  { fprintf(stderr, "%*sDecoding portable bytecode.\n", data->depth, ""); old_a_flag = a_flag; a_flag = (a_flag > (data->debug-1))?a_flag:(data->debug-1); });
2ac4992011-03-09Martin Stjernholm  func.offset = decode_portable_bytecode(data, func.offset);
f26a512003-12-11Henrik Grubbström (Grubba)  EDB(2, a_flag = old_a_flag);
82723d2003-11-25Henrik Grubbström (Grubba)  }
9182912002-05-10Henrik Grubbström (Grubba)  /* opt_flags */ decode_number(opt_flags, data); /* FIXME: * Verify validity of func_flags, func.offset & opt_flags */ /* Expected identifier offset */ decode_number(no, data); EDB(5, {
ef24a82012-01-12Henrik Grubbström (Grubba)  INT_TYPE line;
9182912002-05-10Henrik Grubbström (Grubba)  struct pike_string *file = get_line(func.offset + p->program, p, &line); fprintf(stderr, "%*sdefine_function(\"%s\", X, 0x%04x, 0x%04x,\n" "%*s 0x%04x, 0x%04x)\n"
ef24a82012-01-12Henrik Grubbström (Grubba)  "%*s @ %s:%ld\n",
9182912002-05-10Henrik Grubbström (Grubba)  data->depth, "", Pike_sp[-2].u.string->str, id_flags, func_flags, data->depth, "", func.offset, opt_flags, data->depth, "",
ef24a82012-01-12Henrik Grubbström (Grubba)  file->str, (long)line);
9182912002-05-10Henrik Grubbström (Grubba)  }); /* Alters * * identifiers, identifier_references */ n = define_function(Pike_sp[-2].u.string, Pike_sp[-1].u.type, id_flags, func_flags, &func, opt_flags);
db7fe62014-03-12Arne Goedeke  if ((no < 0 || no >= p->num_identifier_references) ||
564abf2013-11-07Henrik Grubbström (Grubba)  (no != n && (p->identifier_references[no].id_flags != id_flags || p->identifier_references[no].identifier_offset != p->identifier_references[n].identifier_offset || p->identifier_references[no].inherit_offset != 0))) {
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1,
3beae42003-06-02Martin Stjernholm  "Bad function identifier offset: %d\n", no);
9182912002-05-10Henrik Grubbström (Grubba)  } pop_n_elems(2); } break; case ID_ENTRY_CONSTANT: { struct identifier id; struct reference ref; int no; int n;
8c42122008-05-31Henrik Grubbström (Grubba)  id.filename_strno = store_prog_string(c->lex.current_file); id.linenumber = c->lex.current_line;
865d652008-05-16Henrik Grubbström (Grubba)  id.name = Pike_sp[-2].u.string; id.type = Pike_sp[-1].u.type;
9182912002-05-10Henrik Grubbström (Grubba)  /* identifier_flags */ id.identifier_flags = IDENTIFIER_CONSTANT; /* offset */
89378b2010-11-23Henrik Grubbström (Grubba)  decode_number(id.func.const_info.offset, data);
9182912002-05-10Henrik Grubbström (Grubba)  /* FIXME:
89378b2010-11-23Henrik Grubbström (Grubba)  * Verify validity of func.const_info.offset
9182912002-05-10Henrik Grubbström (Grubba)  */ /* run_time_type */ decode_number(id.run_time_type, data);
0e248f2009-08-09Henrik Grubbström (Grubba)  /* opt_flags */ decode_number(id.opt_flags, data);
3cb6de2010-11-25Henrik Grubbström (Grubba)  ref.run_time_type = PIKE_T_UNKNOWN; ref.func.offset = 0;
9182912002-05-10Henrik Grubbström (Grubba)  /* Expected identifier number. */ decode_number(no, data); n = isidentifier(id.name); #ifdef PROFILING id.self_time=0; id.num_calls=0;
5ca7b52012-01-07Jonas Walldén  id.recur_depth=0;
9182912002-05-10Henrik Grubbström (Grubba)  id.total_time=0; #endif /* id_flags */ ref.id_flags = id_flags;
dc672b2008-02-08Henrik Grubbström (Grubba)  EDB(5, fprintf(stderr, "%*sdefining constant(\"%s\", X, 0x%04x)\n", data->depth, "", Pike_sp[-2].u.string->str, id_flags));
9182912002-05-10Henrik Grubbström (Grubba)  /* identifier_offset */ ref.identifier_offset = Pike_compiler->new_program->num_identifiers;
92f3562007-07-03Henrik Grubbström (Grubba)  add_to_identifiers(id);
9182912002-05-10Henrik Grubbström (Grubba) 
dc672b2008-02-08Henrik Grubbström (Grubba)  /* References now held by the new program identifier. */ dmalloc_touch_svalue(Pike_sp-1); dmalloc_touch_svalue(Pike_sp-2); Pike_sp -= 2;
9182912002-05-10Henrik Grubbström (Grubba)  /* ref.inherit_offset */ ref.inherit_offset = 0; /* Alters * * identifiers, identifier_references */
2e0efc2013-11-03Henrik Grubbström (Grubba)  if (n < 0 || (n = override_identifier (&ref, id.name, 0)) < 0) {
9182912002-05-10Henrik Grubbström (Grubba)  n = p->num_identifier_references; add_to_identifier_references(ref); } if (no != n) {
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1,
8d37f12003-06-03Martin Stjernholm  "Bad function identifier offset "
2ac4992011-03-09Martin Stjernholm  "(expected %d, got %d) for %S.\n", no, n, id.name);
9182912002-05-10Henrik Grubbström (Grubba)  } } break;
62b0e92008-02-02Henrik Grubbström (Grubba)  case ID_ENTRY_ALIAS: { int depth; int refno; int no; int n; /* depth */ decode_number(depth, data); /* refno */ decode_number(refno, data); /* FIXME:
3766272014-03-17Henrik Grubbström (Grubba)  * Verify validity of depth and refno.
62b0e92008-02-02Henrik Grubbström (Grubba)  */ /* Expected identifier number. */ decode_number(no, data); EDB(5, fprintf(stderr, "%*slow_define_alias(\"%s\", X, 0x%04x)\n", data->depth, "", Pike_sp[-2].u.string->str, id_flags)); /* Alters * * variable_index, identifiers and * identifier_references */ n = low_define_alias(Pike_sp[-2].u.string, Pike_sp[-1].u.type, id_flags, depth, refno); if (no != n) { ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1,
62b0e92008-02-02Henrik Grubbström (Grubba)  "Bad alias identifier offset "
2ac4992011-03-09Martin Stjernholm  "(expected %d, got %d) for %O.\n", no, n, Pike_sp - 3);
62b0e92008-02-02Henrik Grubbström (Grubba)  } pop_n_elems(2); } break;
9182912002-05-10Henrik Grubbström (Grubba)  case ID_ENTRY_INHERIT: { struct program *prog; struct object *parent = NULL; int parent_identifier; int parent_offset; struct pike_string *name = NULL; int no; decode_number(no, data); if (no != Pike_compiler->new_program->num_identifier_references) {
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1,
3beae42003-06-02Martin Stjernholm  "Bad inherit identifier offset: %d\n", no);
9182912002-05-10Henrik Grubbström (Grubba)  } /* name */
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) == T_STRING) {
9182912002-05-10Henrik Grubbström (Grubba)  name = Pike_sp[-1].u.string;
017b572011-10-28Henrik Grubbström (Grubba)  } else if ((TYPEOF(Pike_sp[-1]) != T_INT) ||
9182912002-05-10Henrik Grubbström (Grubba)  Pike_sp[-1].u.integer) {
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Bad inherit name (not a string): %O\n", Pike_sp - 2);
9182912002-05-10Henrik Grubbström (Grubba)  } /* prog */
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
2e065c2013-11-07Henrik Grubbström (Grubba)  if (!(prog = program_from_svalue(Pike_sp-1))) {
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Bad inherit: Expected program, got: %O\n", Pike_sp - 2);
9182912002-05-10Henrik Grubbström (Grubba)  }
3beae42003-06-02Martin Stjernholm  if (prog == placeholder_program) { ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error (data, Pike_sp - 1,
3beae42003-06-02Martin Stjernholm  "Trying to inherit placeholder program " "(resolver or codec problem).\n"); } if(!(prog->flags & (PROGRAM_FINISHED | PROGRAM_PASS_1_DONE))) { ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error (data, Pike_sp - 1,
3beae42003-06-02Martin Stjernholm  "Cannot inherit a program which is not "
2ac4992011-03-09Martin Stjernholm  "fully compiled yet (resolver or codec " "problem): %O\n", Pike_sp - 2);
3beae42003-06-02Martin Stjernholm  }
9182912002-05-10Henrik Grubbström (Grubba)  /* parent */
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) == T_OBJECT) {
9182912002-05-10Henrik Grubbström (Grubba)  parent = Pike_sp[-1].u.object;
017b572011-10-28Henrik Grubbström (Grubba)  } else if ((TYPEOF(Pike_sp[-1]) != T_INT) ||
9182912002-05-10Henrik Grubbström (Grubba)  Pike_sp[-1].u.integer) {
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Bad inherit: Parent isn't an object: %O\n", Pike_sp - 2);
9182912002-05-10Henrik Grubbström (Grubba)  } /* parent_identifier */ decode_number(parent_identifier, data); /* parent_offset */ decode_number(parent_offset, data); /* Expected number of identifier references. */ decode_number(no, data); if (prog->num_identifier_references != no) {
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Bad number of identifiers " "in inherit (%d != %d).\n",
3beae42003-06-02Martin Stjernholm  no, prog->num_identifier_references);
9182912002-05-10Henrik Grubbström (Grubba)  } EDB(5, fprintf(stderr,
2f71272013-06-15Henrik Grubbström (Grubba)  "%*slower_inherit(..., \"%s\")\n",
9182912002-05-10Henrik Grubbström (Grubba)  data->depth, "", name?name->str:"NULL")); /* Alters * * storage, inherits and identifier_references */
2f71272013-06-15Henrik Grubbström (Grubba)  lower_inherit(prog, parent, parent_identifier, parent_offset + 42, id_flags, name);
9182912002-05-10Henrik Grubbström (Grubba)  pop_n_elems(3); } break; default:
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Unsupported id entry type: %d\n", entry_type);
9182912002-05-10Henrik Grubbström (Grubba)  } decode_number(entry_type, data); }
865d652008-05-16Henrik Grubbström (Grubba)  /* Restore c->lex. */
e614052008-05-17Henrik Grubbström (Grubba)  CALL_AND_UNSET_ONERROR(err2);
865d652008-05-16Henrik Grubbström (Grubba)  c->lex.current_line = save_current_line;
9182912002-05-10Henrik Grubbström (Grubba) #ifdef ENCODE_DEBUG data->depth-=2; #endif UNSET_ONERROR(err); /* De-kludge to get end_first_pass() to free the program. */ Pike_compiler->num_parse_error--; p->flags |= PROGRAM_PASS_1_DONE; /* Fixate & optimize * * lfuns and identifier_index */
fe0b712003-06-12Martin Stjernholm  ref_push_program (p);
9182912002-05-10Henrik Grubbström (Grubba)  if (!(p = end_first_pass(2))) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Failed to decode program.\n");
9182912002-05-10Henrik Grubbström (Grubba)  }
fe0b712003-06-12Martin Stjernholm  pop_stack(); push_program(p);
9182912002-05-10Henrik Grubbström (Grubba) 
6f01232008-05-26Henrik Grubbström (Grubba)  if (c->placeholder) {
ec414a2008-05-26Henrik Grubbström (Grubba)  push_object(placeholder = c->placeholder); c->placeholder = NULL;
6f01232008-05-26Henrik Grubbström (Grubba)  }
e021fe2008-04-14Henrik Grubbström (Grubba)  exit_compiler();
2479e92003-08-05Henrik Grubbström (Grubba) 
8d37f12003-06-03Martin Stjernholm  EDB(5, dump_program_tables(p, data->depth)); #ifdef PIKE_DEBUG check_program (p); #endif
82723d2003-11-25Henrik Grubbström (Grubba)  if (bytecode_method == PIKE_BYTECODE_PORTABLE) {
35892c2003-11-25Henrik Grubbström (Grubba)  /* We've regenerated p->program, so these may be off. */
82723d2003-11-25Henrik Grubbström (Grubba)  local_num_program = p->num_program;
494d7e2004-05-11Henrik Grubbström (Grubba)  local_num_relocations = p->num_relocations;
35892c2003-11-25Henrik Grubbström (Grubba)  local_num_linenumbers = p->num_linenumbers;
82723d2003-11-25Henrik Grubbström (Grubba)  }
9182912002-05-10Henrik Grubbström (Grubba)  /* Verify... */
3beae42003-06-02Martin Stjernholm #define FOO(NUMTYPE,TYPE,ARGTYPE,NAME) \ if (PIKE_CONCAT(local_num_, NAME) != p->PIKE_CONCAT(num_,NAME)) { \ ref_push_program (p); \
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, \
25c8622004-05-12Henrik Grubbström (Grubba)  "Value mismatch for num_" TOSTR(NAME) ": " \
2ac4992011-03-09Martin Stjernholm  "%zd != %zd (bytecode method: %d)\n", \
2d76f22005-05-20Martin Stjernholm  (size_t) PIKE_CONCAT(local_num_, NAME), \ (size_t) p->PIKE_CONCAT(num_, NAME), \
25c8622004-05-12Henrik Grubbström (Grubba)  bytecode_method); \
9182912002-05-10Henrik Grubbström (Grubba)  } #include "program_areas.h" /* Decode the actual constants * * This must be done after the program has been ended. */ for (e=0; e<local_num_constants; e++) { struct program_constant *constant = p->constants+e;
017b572011-10-28Henrik Grubbström (Grubba)  if ((TYPEOF(constant->sval) != T_INT) || (SUBTYPEOF(constant->sval) != NUMBER_UNDEFINED)) {
82723d2003-11-25Henrik Grubbström (Grubba)  /* Already initialized. */
f26a512003-12-11Henrik Grubbström (Grubba)  EDB(5, fprintf(stderr, "%*sskipping constant %d\n", data->depth, "", e));
82723d2003-11-25Henrik Grubbström (Grubba)  continue; }
9182912002-05-10Henrik Grubbström (Grubba)  /* value */
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
9182912002-05-10Henrik Grubbström (Grubba)  /* name */
fe0b712003-06-12Martin Stjernholm  decode_value2(data);
4ea54f2004-05-29Henrik Grubbström (Grubba) #if 0
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(Pike_sp[-1]) == T_STRING) {
9182912002-05-10Henrik Grubbström (Grubba)  constant->name = Pike_sp[-1].u.string;
017b572011-10-28Henrik Grubbström (Grubba)  } else if ((TYPEOF(Pike_sp[-1]) == T_INT) &&
9182912002-05-10Henrik Grubbström (Grubba)  !Pike_sp[-1].u.integer) { constant->name = NULL; } else {
3beae42003-06-02Martin Stjernholm  ref_push_program (p);
2ac4992011-03-09Martin Stjernholm  decode_error(data, Pike_sp - 1, "Name of constant is not a string: %O\n", Pike_sp - 2);
9182912002-05-10Henrik Grubbström (Grubba)  } constant->sval = Pike_sp[-2];
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp-1); dmalloc_touch_svalue(Pike_sp-2);
9182912002-05-10Henrik Grubbström (Grubba)  Pike_sp -= 2;
4ea54f2004-05-29Henrik Grubbström (Grubba) #else /* !0 */ constant->offset = -1; pop_stack(); constant->sval = Pike_sp[-1]; dmalloc_touch_svalue(Pike_sp-1); Pike_sp -= 1; #endif /* 0 */
f26a512003-12-11Henrik Grubbström (Grubba)  EDB(5, fprintf(stderr, "%*sDecoded constant %d to a %s\n", data->depth, "",
017b572011-10-28Henrik Grubbström (Grubba)  e, get_name_of_type(TYPEOF(constant->sval))));
9182912002-05-10Henrik Grubbström (Grubba)  }
c2b4592010-11-22Martin Stjernholm #ifdef ENCODE_DEBUG if (!data->debug) #endif data->pickyness--;
f9b1622003-06-01Martin Stjernholm 
9182912002-05-10Henrik Grubbström (Grubba)  /* The program should be consistent now. */ p->flags &= ~PROGRAM_AVOID_CHECK; EDB(5, fprintf(stderr, "%*sProgram flags: 0x%04x\n", data->depth, "", p->flags));
ec414a2008-05-26Henrik Grubbström (Grubba)  if (placeholder) { if (placeholder->prog != null_program) {
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Placeholder has been zapped during decoding.\n");
ec414a2008-05-26Henrik Grubbström (Grubba)  } debug_malloc_touch(placeholder); free_program(placeholder->prog); add_ref(placeholder->prog = p); placeholder->storage = p->storage_needed ?
a72e632010-07-01Henrik Grubbström (Grubba)  (char *)xcalloc(p->storage_needed, 1) :
ec414a2008-05-26Henrik Grubbström (Grubba)  (char *)NULL; call_c_initializers(placeholder);
0efe6b2008-05-26Henrik Grubbström (Grubba)  if (!data->delay_counter) { call_pike_initializers(placeholder, 0); } else { /* It's not safe to call __INIT() or create() yet, since * there are delayed programs left. */ struct unfinished_obj_link *up = ALLOC_STRUCT(unfinished_obj_link); up->next = data->unfinished_placeholders; data->unfinished_placeholders = up; add_ref(up->o = placeholder); }
ec414a2008-05-26Henrik Grubbström (Grubba)  pop_stack(); }
0efe6b2008-05-26Henrik Grubbström (Grubba)  if (!data->delay_counter) { /* Call the Pike initializers for the delayed placeholders. */ struct unfinished_obj_link *up; while ((up = data->unfinished_placeholders)) { struct object *o; data->unfinished_placeholders = up->next; push_object(o = up->o); free(up); call_pike_initializers(o, 0); pop_stack(); } }
9182912002-05-10Henrik Grubbström (Grubba) #ifdef ENCODE_DEBUG data->depth -= 2; #endif
8d37f12003-06-03Martin Stjernholm  goto decode_done;
9182912002-05-10Henrik Grubbström (Grubba)  }
05590d1998-04-23Fredrik Hübinette (Hubbe)  default:
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "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:
2ac4992011-03-09Martin Stjernholm  decode_error(data, NULL, "Failed to restore string (illegal type %d).\n", what & TAG_MASK);
3ad9861997-01-26Fredrik Hübinette (Hubbe)  }
8d37f12003-06-03Martin Stjernholm  mapping_insert(data->decoded, &entry_id, Pike_sp-1); decode_done:; EDB(2,fprintf(stderr, "%*sDecoded to <%d>: ", data->depth, "", entry_id.u.integer);
b55a122001-07-10Martin Stjernholm  print_svalue(stderr, Pike_sp-1); fputc('\n', stderr);); #ifdef ENCODE_DEBUG data->depth -= 2; #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe) }
997a002001-11-08Fredrik Hübinette (Hubbe) /* Placed after to prevent inlining */ static int init_placeholder(struct object *placeholder) { JMP_BUF rec; /* Initialize the placeholder. */ if(SETJMP(rec)) { dmalloc_touch_svalue(&throw_value); call_handle_error();
fe0b712003-06-12Martin Stjernholm  zap_placeholder(placeholder);
997a002001-11-08Fredrik Hübinette (Hubbe)  UNSETJMP(rec); return 1; }else{ call_pike_initializers(placeholder,0); UNSETJMP(rec); return 0; } }
3ad9861997-01-26Fredrik Hübinette (Hubbe) 
a72ad72001-07-03Henrik Grubbström (Grubba) static struct decode_data *current_decode = NULL;
32789f2005-05-31Martin Stjernholm static void free_decode_data (struct decode_data *data, int delay,
57ed3f2012-12-30Jonas Walldén  int DEBUGUSED(free_after_error))
3ad9861997-01-26Fredrik Hübinette (Hubbe) {
32789f2005-05-31Martin Stjernholm #ifdef PIKE_DEBUG int e; struct keypair *k; #endif
997a002001-11-08Fredrik Hübinette (Hubbe)  debug_malloc_touch(data);
6f7ff82001-07-12Fredrik Hübinette (Hubbe) 
a72ad72001-07-03Henrik Grubbström (Grubba)  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; } } }
997a002001-11-08Fredrik Hübinette (Hubbe)  if(delay) { debug_malloc_touch(data); /* We have been delayed */ return; } #ifdef PIKE_DEBUG
32789f2005-05-31Martin Stjernholm  if (!free_after_error) { NEW_MAPPING_LOOP (data->decoded->data) {
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(k->val) == T_PROGRAM &&
32789f2005-05-31Martin Stjernholm  !(k->val.u.program->flags & PROGRAM_FINISHED)) {
2ac4992011-03-09Martin Stjernholm  decode_error (data, NULL, "Got unfinished program <%O> after decode: %O\n", &k->ind, &k->val);
32789f2005-05-31Martin Stjernholm  } } if(data->unfinished_programs) Pike_fatal("We have unfinished programs left in decode()!\n"); if(data->unfinished_objects) Pike_fatal("We have unfinished objects left in decode()!\n");
0efe6b2008-05-26Henrik Grubbström (Grubba)  if(data->unfinished_placeholders) Pike_fatal("We have unfinished placeholders left in decode()!\n");
32789f2005-05-31Martin Stjernholm  }
997a002001-11-08Fredrik Hübinette (Hubbe) #endif
32789f2005-05-31Martin Stjernholm  free_string (data->data_str);
a63ecd2011-03-19Martin Stjernholm  if (data->codec) free_object (data->codec);
32789f2005-05-31Martin Stjernholm  free_mapping(data->decoded);
997a002001-11-08Fredrik Hübinette (Hubbe)  while(data->unfinished_programs) { struct unfinished_prog_link *tmp=data->unfinished_programs; data->unfinished_programs=tmp->next;
26bb952014-04-27Martin Nilsson  free(tmp);
997a002001-11-08Fredrik Hübinette (Hubbe)  } while(data->unfinished_objects) { struct unfinished_obj_link *tmp=data->unfinished_objects; data->unfinished_objects=tmp->next;
478c7d2008-05-21Henrik Grubbström (Grubba)  free_svalue(&tmp->decode_arg); free_object(tmp->o);
26bb952014-04-27Martin Nilsson  free(tmp);
997a002001-11-08Fredrik Hübinette (Hubbe)  }
32789f2005-05-31Martin Stjernholm 
0efe6b2008-05-26Henrik Grubbström (Grubba)  while(data->unfinished_placeholders) { struct unfinished_obj_link *tmp=data->unfinished_placeholders; data->unfinished_placeholders=tmp->next; free_object(tmp->o);
26bb952014-04-27Martin Nilsson  free(tmp);
0efe6b2008-05-26Henrik Grubbström (Grubba)  }
d45dce2001-08-14Martin Stjernholm #ifdef PIKE_THREADS
0431312003-02-15Henrik Grubbström (Grubba)  data->thread_state = NULL;
32789f2005-05-31Martin Stjernholm  free_object (data->thread_obj);
d45dce2001-08-14Martin Stjernholm #endif
997a002001-11-08Fredrik Hübinette (Hubbe)  free( (char *) data); }
8a86892003-06-05Martin Stjernholm static void low_do_decode (struct decode_data *data)
997a002001-11-08Fredrik Hübinette (Hubbe) {
32789f2005-05-31Martin Stjernholm  current_decode = data; decode_value2(data);
997a002001-11-08Fredrik Hübinette (Hubbe) 
8a86892003-06-05Martin Stjernholm  while (data->ptr < data->len) {
fe0b712003-06-12Martin Stjernholm  decode_value2 (data);
8a86892003-06-05Martin Stjernholm  pop_stack(); } }
32789f2005-05-31Martin Stjernholm #if TWO_PASS_DECODE_WORKS
8a86892003-06-05Martin Stjernholm /* Run pass2 */ int re_decode(struct decode_data *data, int ignored) {
32789f2005-05-31Martin Stjernholm  JMP_BUF recovery; struct svalue orig_thrown; move_svalue (&orig_thrown, &throw_value);
1ab4ac2008-01-26Martin Stjernholm  mark_free_svalue (&throw_value);
32789f2005-05-31Martin Stjernholm  if (SETJMP (recovery)) { UNSETJMP (recovery); call_handle_error(); move_svalue (&throw_value, &orig_thrown); free_decode_data (data, 0, 1); return 0; } else { data->next = current_decode; low_do_decode (data); UNSETJMP (recovery); move_svalue (&throw_value, &orig_thrown); free_decode_data (data, 0, 0); return 1; } } #endif static void error_free_decode_data (struct decode_data *data) { int delay; debug_malloc_touch (data); #if TWO_PASS_DECODE_WORKS delay=unlink_current_supporter(&data->supporter); call_dependants(& data->supporter, 1); #else delay = 0; #endif free_decode_data (data, delay, 1);
3ad9861997-01-26Fredrik Hübinette (Hubbe) }
05590d1998-04-23Fredrik Hübinette (Hubbe) static INT32 my_decode(struct pike_string *tmp,
fe0b712003-06-12Martin Stjernholm  struct object *codec
b55a122001-07-10Martin Stjernholm #ifdef ENCODE_DEBUG , int debug #endif )
3ad9861997-01-26Fredrik Hübinette (Hubbe) {
997a002001-11-08Fredrik Hübinette (Hubbe)  struct decode_data *data;
99e4f02004-10-15Henrik Grubbström (Grubba)  ONERROR err;
a72ad72001-07-03Henrik Grubbström (Grubba)  /* Attempt to avoid infinite recursion on circular structures. */ for (data = current_decode; data; data=data->next) {
a63ecd2011-03-19Martin Stjernholm  if (data->raw == tmp && (codec ? data->codec == codec : !data->explicit_codec)
d45dce2001-08-14Martin Stjernholm #ifdef PIKE_THREADS
0431312003-02-15Henrik Grubbström (Grubba)  && data->thread_state == Pike_interpreter.thread_state
d45dce2001-08-14Martin Stjernholm #endif ) {
a72ad72001-07-03Henrik Grubbström (Grubba)  struct svalue *res;
8133372008-05-30Martin Stjernholm  struct svalue val = SVALUE_INIT_INT (0);
d45dce2001-08-14Martin Stjernholm  val.u.integer = COUNTER_START;
a72ad72001-07-03Henrik Grubbström (Grubba)  if ((res = low_mapping_lookup(data->decoded, &val))) { push_svalue(res); return 1; } /* Possible recursion detected. */ /* return 0; */ } }
997a002001-11-08Fredrik Hübinette (Hubbe)  data=ALLOC_STRUCT(decode_data);
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(data->counter, T_INT, NUMBER_NUMBER, integer, COUNTER_START);
32789f2005-05-31Martin Stjernholm  data->data_str = tmp;
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;
a63ecd2011-03-19Martin Stjernholm  data->explicit_codec = codec ? 1 : 0;
05590d1998-04-23Fredrik Hübinette (Hubbe)  data->pickyness=0;
997a002001-11-08Fredrik Hübinette (Hubbe)  data->pass=1;
20d57c2001-07-02Fredrik Hübinette (Hubbe)  data->unfinished_programs=0;
6f7ff82001-07-12Fredrik Hübinette (Hubbe)  data->unfinished_objects=0;
0efe6b2008-05-26Henrik Grubbström (Grubba)  data->unfinished_placeholders = NULL; data->delay_counter = 0;
a72ad72001-07-03Henrik Grubbström (Grubba)  data->raw = tmp; data->next = current_decode;
d45dce2001-08-14Martin Stjernholm #ifdef PIKE_THREADS
0431312003-02-15Henrik Grubbström (Grubba)  data->thread_state = Pike_interpreter.thread_state;
32789f2005-05-31Martin Stjernholm  data->thread_obj = Pike_interpreter.thread_state->thread_obj;
d45dce2001-08-14Martin Stjernholm #endif
b55a122001-07-10Martin Stjernholm #ifdef ENCODE_DEBUG data->debug = debug; data->depth = -2; #endif
3ad9861997-01-26Fredrik Hübinette (Hubbe) 
997a002001-11-08Fredrik Hübinette (Hubbe)  if (tmp->size_shift || data->len < 5 || GETC() != 182 || GETC() != 'k' || GETC() != 'e' || GETC() != '0') { free( (char *) data);
3ad9861997-01-26Fredrik Hübinette (Hubbe)  return 0;
997a002001-11-08Fredrik Hübinette (Hubbe)  }
3ad9861997-01-26Fredrik Hübinette (Hubbe)  data->decoded=allocate_mapping(128);
32789f2005-05-31Martin Stjernholm  add_ref (data->data_str);
a63ecd2011-03-19Martin Stjernholm  if (data->codec) add_ref (data->codec);
ee21042005-06-01Henrik Grubbström (Grubba) #ifdef PIKE_THREADS
32789f2005-05-31Martin Stjernholm  add_ref (data->thread_obj);
ee21042005-06-01Henrik Grubbström (Grubba) #endif
32789f2005-05-31Martin Stjernholm  SET_ONERROR(err, error_free_decode_data, data);
99e4f02004-10-15Henrik Grubbström (Grubba) 
32789f2005-05-31Martin Stjernholm #if TWO_PASS_DECODE_WORKS
997a002001-11-08Fredrik Hübinette (Hubbe)  init_supporter(& data->supporter,
c6cf602001-12-13Martin Stjernholm  (supporter_callback *) re_decode,
997a002001-11-08Fredrik Hübinette (Hubbe)  (void *)data);
32789f2005-05-31Martin Stjernholm #endif
997a002001-11-08Fredrik Hübinette (Hubbe) 
8a86892003-06-05Martin Stjernholm  low_do_decode (data);
a72ad72001-07-03Henrik Grubbström (Grubba) 
32789f2005-05-31Martin Stjernholm  UNSET_ONERROR(err); { int delay; #if TWO_PASS_DECODE_WORKS delay=unlink_current_supporter(&data->supporter); call_dependants(& data->supporter, 1); #else delay = 0;
99e4f02004-10-15Henrik Grubbström (Grubba) #endif
32789f2005-05-31Martin Stjernholm  free_decode_data (data, delay, 0); }
99e4f02004-10-15Henrik Grubbström (Grubba) 
3ad9861997-01-26Fredrik Hübinette (Hubbe)  return 1; }
81a3162002-12-07Henrik Grubbström (Grubba) /*! @class MasterObject */
3657402011-03-19Martin Stjernholm /*! @decl program Encoder;
81a3162002-12-07Henrik Grubbström (Grubba)  *!
3657402011-03-19Martin Stjernholm  *! This program in the master is cloned and used as codec by *! @[encode_value] if it wasn't given any codec. An instance is only *! created on-demand the first time @[encode_value] encounters *! something for which it needs a codec, i.e. an object, program, or *! function.
81a3162002-12-07Henrik Grubbström (Grubba)  *!
3657402011-03-19Martin Stjernholm  *! @seealso *! @[Encoder], @[Pike.Encoder] */ /*! @decl program Decoder; *! *! This program in the master is cloned and used as codec by *! @[decode_value] if it wasn't given any codec. An instance is only *! created on-demand the first time @[decode_value] encounters *! something for which it needs a codec, i.e. the result of a call to *! @[Pike.Encoder.nameof]. *! *! @seealso *! @[Decoder], @[Pike.Decoder]
81a3162002-12-07Henrik Grubbström (Grubba)  */
81f66c2003-12-16Henrik Grubbström (Grubba) /*! @endclass */
3657402011-03-19Martin Stjernholm /*! @class Encoder
81a3162002-12-07Henrik Grubbström (Grubba)  *!
3657402011-03-19Martin Stjernholm  *! Codec used by @[encode_value()] to encode objects, functions and *! programs. Its purpose is to look up some kind of identifier for *! them, so they can be mapped back to the corresponding instance *! by @[decode_value()], rather than creating a new copy.
81a3162002-12-07Henrik Grubbström (Grubba)  */ /*! @decl mixed nameof(object|function|program x) *! *! Called by @[encode_value()] to encode objects, functions and programs. *! *! @returns *! Returns something encodable on success, typically a string. *! The returned value will be passed to the corresponding *! @[objectof()], @[functionof()] or @[programof()] by *! @[decode_value()]. *!
3657402011-03-19Martin Stjernholm  *! If it returns @[UNDEFINED] then @[encode_value] starts to encode *! the thing recursively, so that @[decode_value] later will *! rebuild a copy.
81a3162002-12-07Henrik Grubbström (Grubba)  *! *! @note *! @[encode_value()] has fallbacks for some classes of objects, *! functions and programs. *! *! @seealso
3657402011-03-19Martin Stjernholm  *! @[Decoder.objectof()], @[Decoder.functionof()], *! @[Decoder.objectof()] */ /*! @endclass */ /*! @class Decoder *! *! Codec used by @[decode_value()] to decode objects, functions and *! programs which have been encoded by @[Encoder.nameof] in the *! corresponding @[Encoder] object.
81a3162002-12-07Henrik Grubbström (Grubba)  */
fe0b712003-06-12Martin Stjernholm /*! @decl object objectof(string data)
81a3162002-12-07Henrik Grubbström (Grubba)  *!
fe0b712003-06-12Martin Stjernholm  *! Decode object encoded in @[data].
81a3162002-12-07Henrik Grubbström (Grubba)  *! *! This function is called by @[decode_value()] when it encounters
fe0b712003-06-12Martin Stjernholm  *! encoded objects.
81a3162002-12-07Henrik Grubbström (Grubba)  *! *! @param data
3657402011-03-19Martin Stjernholm  *! Encoding of some object as returned by @[Encoder.nameof()].
81a3162002-12-07Henrik Grubbström (Grubba)  *!
fe0b712003-06-12Martin Stjernholm  *! @returns *! Returns the decoded object.
81a3162002-12-07Henrik Grubbström (Grubba)  *!
fe0b712003-06-12Martin Stjernholm  *! @seealso *! @[functionof()], @[programof()] */ /*! @decl function functionof(string data) *! *! Decode function encoded in @[data].
81a3162002-12-07Henrik Grubbström (Grubba)  *!
fe0b712003-06-12Martin Stjernholm  *! This function is called by @[decode_value()] when it encounters *! encoded functions. *! *! @param data
3657402011-03-19Martin Stjernholm  *! Encoding of some function as returned by @[Encoder.nameof()].
81a3162002-12-07Henrik Grubbström (Grubba)  *! *! @returns
fe0b712003-06-12Martin Stjernholm  *! Returns the decoded function. *! *! @seealso *! @[objectof()], @[programof()] */ /*! @decl program programof(string data) *! *! Decode program encoded in @[data]. *! *! This function is called by @[decode_value()] when it encounters *! encoded programs. *! *! @param data
3657402011-03-19Martin Stjernholm  *! Encoding of some program as returned by @[Encoder.nameof()].
fe0b712003-06-12Martin Stjernholm  *! *! @returns *! Returns the decoded program. *! *! @seealso *! @[functionof()], @[objectof()]
81a3162002-12-07Henrik Grubbström (Grubba)  */
fe0b712003-06-12Martin Stjernholm /*! @decl object __register_new_program(program p)
81a3162002-12-07Henrik Grubbström (Grubba)  *!
3657402011-03-19Martin Stjernholm  *! Called to register the program that is being decoded. Might get *! called repeatedly with several other programs that are being *! decoded recursively. The only safe assumption is that when the *! top level thing being decoded is a program, then the first call *! will be with the unfinished embryo that will later become that *! program.
fe0b712003-06-12Martin Stjernholm  *! *! @returns *! Returns either zero or a placeholder object. A placeholder *! object must be a clone of @[__null_program]. When the program is *! finished, the placeholder object will be converted to a clone of *! it. This is used for pike module objects.
81a3162002-12-07Henrik Grubbström (Grubba)  */ /*! @endclass */
3657402011-03-19Martin Stjernholm /*! @class Codec *! *! An @[Encoder] and a @[Decoder] lumped into a single instance which *! can be used