2003-06-03
2003-06-03 18:15:31 by Martin Stjernholm <mast@lysator.liu.se>
-
8d37f14fed8d4a45f6153ca645241a9c145eab27
(489 lines)
(+320/-169)
[
Show
| Annotate
]
Branch: 7.9
Added forward references to programs to solve cyclicity problems in
decode_value.
Rev: src/encode.c:1.176
2:
|| 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.
- || $Id: encode.c,v 1.175 2003/06/02 21:16:51 mast Exp $
+ || $Id: encode.c,v 1.176 2003/06/03 18:15:31 mast Exp $
*/
#include "global.h"
27:
#include "bignum.h"
#include "pikecode.h"
- RCSID("$Id: encode.c,v 1.175 2003/06/02 21:16:51 mast Exp $");
+ RCSID("$Id: encode.c,v 1.176 2003/06/03 18:15:31 mast Exp $");
- /* #define ENCODE_DEBUG */
+ #define ENCODE_DEBUG
/* Use the old encoding method for programs. */
/* #define OLD_PIKE_ENCODE_PROGRAM */
90:
#define TAG_INT 8
#define TAG_TYPE 9 /* Not supported yet */
+ #define TAG_DELAYED 14 /* Note: Coincides with T_ZERO. */
#define TAG_AGAIN 15
#define TAG_MASK 15
#define TAG_NEG 16
#define TAG_SMALL 32
#define SIZE_SHIFT 6
#define MAX_SMALL (1<<(8-SIZE_SHIFT))
- #define COUNTER_START -MAX_SMALL
+ #define COUNTER_START 1
/* Entries used to encode the identifier_references table. */
#define ID_ENTRY_RAW -2
112:
struct object *codec;
struct svalue counter;
struct mapping *encoded;
+ /* The encoded mapping maps encoded things to their entry IDs. A
+ * negative value means that it's a forward reference to a thing not
+ * yet encoded. */
+ struct array *delayed;
dynamic_buffer buf;
#ifdef ENCODE_DEBUG
int debug, depth;
#endif
};
- static void encode_value2(struct svalue *val, struct encode_data *data);
+ static void encode_value2(struct svalue *val, struct encode_data *data, int force_dump);
#define addstr(s, l) low_my_binary_strcat((s), (l), &(data->buf))
#define addchar(t) low_my_putchar((char)(t), &(data->buf))
278:
sval.subtype = 0;
sval.u.string = (void *)t->car;
- encode_value2(&sval, data);
+ encode_value2(&sval, data, 0);
}
t=t->cdr;
goto one_more_type;
378:
}else{
push_int(0);
}
- encode_value2(Pike_sp-1, data);
+ /* 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);
pop_stack();
break;
}
419:
}
}
- static void encode_value2(struct svalue *val, struct encode_data *data)
+ /* force_dump == 0: Maybe dump the thing later, and only a forward
+ * reference here (applies to programs only).
+ *
+ * force_dump == 1: Dump the thing now.
+ *
+ * force_dump == 2: A forward reference has been encoded to this
+ * thing. Now it's time to dump it. */
-
+ static void encode_value2(struct svalue *val, struct encode_data *data, int force_dump)
+
#ifdef PIKE_DEBUG
#undef encode_value2
- #define encode_value2(X,Y) do { struct svalue *_=Pike_sp; encode_value2_(X,Y); if(Pike_sp!=_) Pike_fatal("encode_value2 failed!\n"); } while(0)
+ #define encode_value2(X,Y,Z) do { \
+ struct svalue *_=Pike_sp; \
+ encode_value2_(X,Y,Z); \
+ if(Pike_sp!=_) Pike_fatal("encode_value2 failed!\n"); \
+ } while(0)
#endif
{
435:
};
INT32 i;
struct svalue *tmp;
+ struct svalue entry_id;
#ifdef ENCODE_DEBUG
data->depth += 2;
447:
if((tmp=low_mapping_lookup(data->encoded, val)))
{
+ entry_id = *tmp; /* It's always a small integer. */
+ if (entry_id.u.integer < 0) entry_id.u.integer = -entry_id.u.integer;
+ if (force_dump && tmp->u.integer < 0) {
+ EDB(1,
+ fprintf(stderr, "%*sEncoding delayed thing to <%d>: ",
+ data->depth, "", entry_id.u.integer);
+ if(data->debug == 1)
+ {
+ fprintf(stderr,"TAG%d",val->type);
+ }else{
+ print_svalue(stderr, val);
+
+ }
+ 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, "", tmp->u.integer));
- code_entry(TAG_AGAIN, tmp->u.integer, data);
+ data->depth, "", entry_id.u.integer));
+ code_entry(TAG_AGAIN, entry_id.u.integer, data);
goto encode_done;
- }else if (val->type != T_TYPE) {
+ }
+ }else {
+ #ifdef PIKE_DEBUG
+ if (force_dump == 2)
+ Pike_fatal ("Didn't find old entry for delay encoded thing.\n");
+ #endif
+ if (val->type != T_TYPE) {
+ entry_id = data->counter; /* It's always a small integer. */
EDB(1,fprintf(stderr, "%*sEncoding to <%d>: ",
- data->depth, "", data->counter.u.integer);
+ data->depth, "", entry_id.u.integer);
if(data->debug == 1)
{
fprintf(stderr,"TAG%d",val->type);
462:
}
fputc('\n', stderr););
- mapping_insert(data->encoded, val, &data->counter);
+ mapping_insert(data->encoded, val, &entry_id);
data->counter.u.integer++;
}
-
+ }
-
+
switch(val->type)
{
case T_INT:
483: Inside #if SIZEOF_INT_TYPE > 4 and #if defined(AUTO_BIGNUM)
#ifdef AUTO_BIGNUM
push_int(i);
convert_stack_top_to_bignum();
- encode_value2(Pike_sp-1,data);
+ encode_value2(Pike_sp-1,data, 0);
pop_stack();
#else
Pike_error ("Cannot encode integers with more than 32 bits "
669:
case T_ARRAY:
code_entry(TAG_ARRAY, val->u.array->size, data);
for(i=0; i<val->u.array->size; i++)
- encode_value2(ITEM(val->u.array)+i, data);
+ encode_value2(ITEM(val->u.array)+i, data, 0);
break;
case T_MAPPING:
700:
code_entry(TAG_MAPPING, Pike_sp[-2].u.array->size,data);
for(i=0; i<Pike_sp[-2].u.array->size; i++)
{
- encode_value2(ITEM(Pike_sp[-2].u.array)+i, data); /* indices */
- encode_value2(ITEM(Pike_sp[-1].u.array)+i, data); /* values */
+ encode_value2(ITEM(Pike_sp[-2].u.array)+i, data, 0); /* indices */
+ encode_value2(ITEM(Pike_sp[-1].u.array)+i, data, 0); /* values */
}
pop_n_elems(2);
break;
738:
order_array(Pike_sp[-1].u.array, order);
free((char *) order);
for (i = 0; i < Pike_sp[-1].u.array->size; i++)
- encode_value2(ITEM(Pike_sp[-1].u.array)+i, data);
+ encode_value2(ITEM(Pike_sp[-1].u.array)+i, data, 0);
pop_stack();
}
else {
746: Inside #if defined(PIKE_NEW_MULTISETS)
struct svalue ind;
union msnode *node = low_multiset_first (l->msd);
for (; node; node = low_multiset_next (node))
- encode_value2 (low_use_multiset_index (node, ind), data);
+ encode_value2 (low_use_multiset_index (node, ind), data, 0);
#else
for(i=0; i<l->ind->size; i++)
- encode_value2(ITEM(l->ind)+i, data);
+ encode_value2(ITEM(l->ind)+i, data, 0);
#endif
}
#ifdef PIKE_NEW_MULTISETS
775: Inside #if defined(AUTO_BIGNUM)
apply(val->u.object,"digits",1);
if(Pike_sp[-1].type != T_STRING)
Pike_error("Gmp.mpz->digits did not return a string!\n");
- encode_value2(Pike_sp-1, data);
+ encode_value2(Pike_sp-1, data, 0);
pop_stack();
break;
}
794:
if(Pike_sp[-1].subtype == NUMBER_UNDEFINED)
{
int to_change = data->buf.s.len;
- struct svalue tmp=data->counter;
- tmp.u.integer--;
+ struct svalue tmp = entry_id;
EDB(5,fprintf(stderr, "%*s(UNDEFINED)\n", data->depth, ""));
808:
/* Code the program */
code_entry(TAG_OBJECT, 3,data);
- encode_value2(Pike_sp-1, data);
+ encode_value2(Pike_sp-1, data, 0);
pop_stack();
push_svalue(val);
846:
code_entry(TAG_OBJECT, 0,data);
break;
}
- encode_value2(Pike_sp-1, data);
+ encode_value2(Pike_sp-1, data, 0);
pop_stack();
break;
865:
val->u.object->prog)==val->subtype)
{
/* We have to remove ourself from the cache for now */
- struct svalue tmp=data->counter;
- tmp.u.integer--;
+ struct svalue tmp = entry_id;
map_delete(data->encoded, val);
code_entry(TAG_FUNCTION, 1, data);
push_svalue(val);
Pike_sp[-1].type=T_OBJECT;
- encode_value2(Pike_sp-1, data);
+ encode_value2(Pike_sp-1, data, 0);
ref_push_string(ID_FROM_INT(val->u.object->prog, val->subtype)->name);
- encode_value2(Pike_sp-1, data);
+ encode_value2(Pike_sp-1, data, 0);
pop_n_elems(3);
/* Put value back in cache */
886:
}
code_entry(TAG_FUNCTION, 0, data);
- encode_value2(Pike_sp-1, data);
+ encode_value2(Pike_sp-1, data, 0);
pop_stack();
break;
897:
if (val->u.program->id < PROG_DYNAMIC_ID_START) {
code_entry(TAG_PROGRAM, 3, data);
push_int(val->u.program->id);
- encode_value2(Pike_sp-1, data);
+ encode_value2(Pike_sp-1, data, 0);
pop_stack();
break;
}
911:
if(Pike_sp[-1].type == T_INT && Pike_sp[-1].subtype == NUMBER_UNDEFINED)
{
struct program *p=val->u.program;
+ pop_stack();
if( (p->flags & PROGRAM_HAS_C_METHODS) || p->event_handler )
{
if(p->parent)
{
/* We have to remove ourself from the cache for now */
- struct svalue tmp=data->counter;
- tmp.u.integer--;
+ struct svalue tmp = entry_id;
map_delete(data->encoded, val);
code_entry(TAG_PROGRAM, 2, data);
ref_push_program(p->parent);
- encode_value2(Pike_sp-1,data);
+ encode_value2(Pike_sp-1,data, 0);
ref_push_program(p);
f_function_name(1);
if(Pike_sp[-1].type == PIKE_T_INT)
Pike_error("Cannot encode C programs.\n");
- encode_value2(Pike_sp-1, data);
+ encode_value2(Pike_sp-1, data, 0);
pop_n_elems(3);
941:
Pike_error("Cannot encode C programs.\n");
}
+ #ifdef OLD_PIKE_ENCODE_PROGRAM
EDB(1,
- fprintf(stderr, "%*sencode: encoding program\n",
+ fprintf(stderr, "%*sencode: encoding program in old style\n",
data->depth, ""));
- #ifdef OLD_PIKE_ENCODE_PROGRAM
-
+
/* Type 1 -- Old-style encoding. */
code_entry(TAG_PROGRAM, 1, data);
f_version(0);
- encode_value2(Pike_sp-1,data);
+ encode_value2(Pike_sp-1,data, 0);
pop_stack();
code_number(p->flags,data);
code_number(p->storage_needed,data);
967: Inside #if defined(OLD_PIKE_ENCODE_PROGRAM)
ref_push_program(p->parent);
else
push_int(0);
- encode_value2(Pike_sp-1,data); /**/
+ encode_value2(Pike_sp-1,data, 0); /**/
pop_stack();
#define FOO(NUMTYPE,TYPE,ARGTYPE,NAME) \
1041:
Pike_error("Failed to encode inherit #%d\n", d);
push_int(0);
}
- encode_value2(Pike_sp-1,data);
+ encode_value2(Pike_sp-1,data, 1);
pop_stack();
adddata3(p->inherits[d].name);
1073:
for(d=0;d<p->num_constants;d++)
{
- encode_value2(& p->constants[d].sval, data);
+ encode_value2(& p->constants[d].sval, data, 0);
adddata3(p->constants[d].name);
}
#else /* !OLD_PIKE_ENCODE_PROGRAM */
- /* Type 4 -- Portable encoding. */
- code_entry(type_to_tag(val->type), 4, data);
+ /* Portable encoding (4 and 5). */
-
+ if (!force_dump) {
+ /* 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);
+ tmp->u.integer = -tmp->u.integer;
+ goto encode_done;
+ }
+
+ EDB(1, fprintf(stderr, "%*sencode: encoding program in new style\n",
+ data->depth, ""));
+ code_entry(TAG_PROGRAM, 4, data);
+
/* Byte-order. */
code_number(PIKE_BYTEORDER, data);
1090:
/* version */
f_version(0);
- encode_value2(Pike_sp-1, data);
+ encode_value2(Pike_sp-1, data, 0);
pop_stack();
/* parent */
1099:
} else {
push_int(0);
}
- encode_value2(Pike_sp-1, data);
+ encode_value2(Pike_sp-1, data, 0);
pop_stack();
/* num_* */
1148:
/* strings */
for(d=0;d<p->num_strings;d++) {
str_sval.u.string = p->strings[d];
- encode_value2(&str_sval, data);
+ encode_value2(&str_sval, data, 0);
}
}
1181:
d_max = p->inherits[inherit_num].identifier_ref_offset;
}
+ EDB (4, fprintf (stderr, "%*sencode: inherit_num: %d, d_max: %d\n",
+ data->depth, "", inherit_num, d_max););
+
/* Fix locally defined identifiers. */
for (; d < d_max; d++) {
struct reference *ref = p->identifier_references + d;
1258:
/* name */
str_sval.u.string = id->name;
- encode_value2(&str_sval, data);
+ encode_value2(&str_sval, data, 0);
/* offset */
code_number(id->func.offset, data);
/* type */
ref_push_type_value(id->type);
- encode_value2(Pike_sp-1, data);
+ encode_value2(Pike_sp-1, data, 0);
pop_stack();
/* run-time type */
1282:
/* name */
str_sval.u.string = id->name;
- encode_value2(&str_sval, data);
+ encode_value2(&str_sval, data, 0);
/* type */
ref_push_type_value(id->type);
- encode_value2(Pike_sp-1, data);
+ encode_value2(Pike_sp-1, data, 0);
pop_stack();
/* func_flags (aka identifier_flags) */
1314:
/* name */
str_sval.u.string = id->name;
- encode_value2(&str_sval, data);
+ encode_value2(&str_sval, data, 0);
/* type */
ref_push_type_value(id->type);
- encode_value2(Pike_sp-1, data);
+ encode_value2(Pike_sp-1, data, 0);
pop_stack();
}
}
1374:
/* name */
str_sval.u.string = inh->name;
- encode_value2(&str_sval, data);
+ encode_value2(&str_sval, data, 0);
/* prog */
ref_push_program(inh->prog);
- encode_value2(Pike_sp-1, data);
+ encode_value2(Pike_sp-1, data, 1);
pop_stack();
/* parent */
1387:
} else {
push_int(0);
}
- encode_value2(Pike_sp-1, data);
+ encode_value2(Pike_sp-1, data, 0);
pop_stack();
/* parent_identifier */
1424:
for(d=0;d<p->num_constants;d++)
{
/* value */
- encode_value2(&p->constants[d].sval, data);
+ encode_value2(&p->constants[d].sval, data, 0);
/* name */
if (p->constants[d].name) {
str_sval.u.string = p->constants[d].name;
- encode_value2(&str_sval, data);
+ encode_value2(&str_sval, data, 0);
} else {
push_int(0);
- encode_value2(Pike_sp-1, data);
+ encode_value2(Pike_sp-1, data, 0);
dmalloc_touch_svalue(Pike_sp-1);
Pike_sp--;
}
1441:
#endif /* OLD_PIKE_ENCODE_PROGRAM */
}else{
code_entry(TAG_PROGRAM, 0, data);
- encode_value2(Pike_sp-1, data);
- }
+ encode_value2(Pike_sp-1, data, 0);
pop_stack();
-
+ }
break;
}
}
1459:
{
toss_buffer(& data->buf);
free_mapping(data->encoded);
+ free_array(data->delayed);
}
/*! @decl string encode_value(mixed value, object|void codec)
1495:
{
ONERROR tmp;
struct encode_data d, *data;
+ int i;
data=&d;
check_all_args("encode_value", args, BIT_MIXED, BIT_VOID | BIT_OBJECT,
1510:
initialize_buf(&data->buf);
data->canonic = 0;
data->encoded=allocate_mapping(128);
+ data->delayed = allocate_array (0);
data->counter.type=T_INT;
data->counter.u.integer=COUNTER_START;
if(args > 1)
1525:
SET_ONERROR(tmp, free_encode_data, data);
addstr("\266ke0", 4);
- encode_value2(Pike_sp-args, data);
+
+ encode_value2(Pike_sp-args, data, 1);
+
+ for (i = 0; i < data->delayed->size; i++)
+ encode_value2 (ITEM(data->delayed) + i, data, 2);
+
UNSET_ONERROR(tmp);
free_mapping(data->encoded);
1556:
{
ONERROR tmp;
struct encode_data d, *data;
+ int i;
data=&d;
check_all_args("encode_value_canonic", args, BIT_MIXED, BIT_VOID | BIT_OBJECT,
1571:
initialize_buf(&data->buf);
data->canonic = 1;
data->encoded=allocate_mapping(128);
+ data->delayed = allocate_array (0);
data->counter.type=T_INT;
data->counter.u.integer=COUNTER_START;
if(args > 1)
1586:
SET_ONERROR(tmp, free_encode_data, data);
addstr("\266ke0", 4);
- encode_value2(Pike_sp-args, data);
+
+ encode_value2(Pike_sp-args, data, 1);
+
+ for (i = 0; i < data->delayed->size; i++)
+ encode_value2 (ITEM(data->delayed) + i, data, 2);
+
UNSET_ONERROR(tmp);
free_mapping(data->encoded);
1982:
#define SETUP_DECODE_MEMOBJ(TYPE, U, VAR, ALLOCATE,SCOUR) do { \
struct svalue *tmpptr; \
+ struct svalue tmp; \
if(data->pass > 1 && \
- (tmpptr=low_mapping_lookup(data->decoded, & data->counter))) \
+ (tmpptr=low_mapping_lookup(data->decoded, & entry_id))) \
{ \
tmp=*tmpptr; \
VAR=tmp.u.U; \
1991:
}else{ \
tmp.type=TYPE; \
tmp.u.U=VAR=ALLOCATE; \
- mapping_insert(data->decoded, & data->counter, &tmp); \
+ mapping_insert(data->decoded, & entry_id, &tmp); \
/* 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. \
*/ \
sub_ref(VAR); \
} \
- data->counter.u.integer++; \
+
}while(0)
/* This really needs to disable threads.... */
2069:
{
INT32 what, e, num, numh;
- struct svalue tmp, *tmp2;
+ struct svalue entry_id, *tmp2;
+ struct svalue *delayed_enc_val;
#ifdef ENCODE_DEBUG
data->depth += 2;
2077:
DECODE("decode_value2");
- #ifdef ENCODE_DEBUG
- if(data->debug)
- {
- if((what & TAG_MASK ) == TAG_AGAIN)
- fprintf(stderr, "%*sDecoding TAG_AGAIN from <%d>\n",
- data->depth, "", num);
-
- else
- if(data->debug > 1)
- fprintf(stderr, "%*sDecoding to <%d>: TAG%d (%d)\n",
- data->depth, "", data->counter.u.integer ,
- what & TAG_MASK, num);
- }
- #endif
-
- check_stack(1);
-
+
switch(what & TAG_MASK)
{
-
+ case TAG_DELAYED:
+ EDB (2, fprintf(stderr, "%*sDecoding delay encoded from <%d>\n",
+ data->depth, "", num););
+ entry_id.type = T_INT;
+ entry_id.subtype = 0;
+ entry_id.u.integer = num;
+ if (!(delayed_enc_val = low_mapping_lookup (data->decoded, &entry_id)))
+ Pike_error ("Failed to find previous record of delay encoded entry <%d>.\n",
+ num);
+ DECODE ("decode_value2");
+ break;
+
case TAG_AGAIN:
- tmp.type=T_INT;
- tmp.subtype=0;
- tmp.u.integer=num;
- if((tmp2=low_mapping_lookup(data->decoded, &tmp)))
+ EDB (1, fprintf(stderr, "%*sDecoding TAG_AGAIN from <%d>\n",
+ data->depth, "", num););
+ entry_id.type=T_INT;
+ entry_id.subtype=0;
+ entry_id.u.integer=num;
+ if((tmp2=low_mapping_lookup(data->decoded, &entry_id)))
{
push_svalue(tmp2);
}else{
Pike_error("Failed to decode TAG_AGAIN entry <%d>.\n", num);
}
- #ifdef ENCODE_DEBUG
- data->depth -= 2;
- #endif
- return;
+ goto decode_done;
- case TAG_INT:
- tmp.type = T_INT;
- tmp=data->counter;
+ default:
+ entry_id = data->counter;
data->counter.u.integer++;
-
+ /* 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:
push_int(num);
break;
case TAG_STRING:
{
struct pike_string *str;
- tmp.type = T_INT;
- tmp=data->counter;
- data->counter.u.integer++;
+
get_string_data(str, num, data);
push_string(str);
break;
2140:
EDB(2,fprintf(stderr, "Mantissa: %10g\n", res));
- tmp = data->counter;
- data->counter.u.integer++;
-
+
DECODE("float");
EDB(2,fprintf(stderr, "Exponent: %d\n", num));
2190:
check_type_string(t);
push_type_value(t);
- tmp.type = T_INT;
- tmp = data->counter;
+ entry_id = data->counter;
data->counter.u.integer++;
}
break;
2208:
Pike_error("Failed to decode array. (not enough data)\n");
EDB(2,fprintf(stderr, "%*sDecoding array of size %d to <%d>\n",
- data->depth, "", num, data->counter.u.integer));
+ data->depth, "", num, entry_id.u.integer));
SETUP_DECODE_MEMOBJ(T_ARRAY, array, a, allocate_array(num),
free_svalues(ITEM(a), a->size, a->type_field));
2222:
}
a->type_field = types;
ref_push_array(a);
- #ifdef ENCODE_DEBUG
- data->depth -= 2;
- #endif
- return;
+ goto decode_done;
}
case TAG_MAPPING:
2239:
Pike_error("Failed to decode mapping. (not enough data)\n");
EDB(2,fprintf(stderr, "%*sDecoding mapping of size %d to <%d>\n",
- data->depth, "", num, data->counter.u.integer));
+ data->depth, "", num, entry_id.u.integer));
SETUP_DECODE_MEMOBJ(T_MAPPING, mapping, m, allocate_mapping(num), ; );
2251:
pop_n_elems(2);
}
ref_push_mapping(m);
- #ifdef ENCODE_DEBUG
- data->depth -= 2;
- #endif
- return;
+ goto decode_done;
}
case TAG_MULTISET:
2272:
/* NOTE: This code knows stuff about the implementation of multisets...*/
EDB(2,fprintf(stderr, "%*sDecoding multiset of size %d to <%d>\n",
- data->depth, "", num, data->counter.u.integer));
+ data->depth, "", num, entry_id.u.integer));
#ifdef PIKE_NEW_MULTISETS
SETUP_DECODE_MEMOBJ (T_MULTISET, multiset, m,
allocate_multiset (0, 0, NULL), ;);
2304:
order_multiset(m);
#endif
ref_push_multiset(m);
- #ifdef ENCODE_DEBUG
- data->depth -= 2;
- #endif
- return;
+ goto decode_done;
}
case TAG_OBJECT:
{
- tmp=data->counter;
- data->counter.u.integer++;
-
+
decode_value2(data);
switch(num)
2341:
decode_error (NULL, Pike_sp - 1,
"Failed to decode program for object. Got: ");
EDB(1,fprintf(stderr, "%*sDecoded a failed object to <%d>: ",
- data->depth, "", tmp.u.integer);
+ data->depth, "", entry_id.u.integer);
print_svalue(stderr, Pike_sp-1);
fputc('\n', stderr););
decode_value2(data);
2371:
}
EDB(2,fprintf(stderr, "%*sDecoded an object to <%d>: ",
- data->depth, "", tmp.u.integer);
+ data->depth, "", entry_id.u.integer);
print_svalue(stderr, Pike_sp-1);
fputc('\n', stderr););
2427:
}
case TAG_FUNCTION:
- tmp=data->counter;
- data->counter.u.integer++;
+
decode_value2(data);
switch(num)
2501:
{
struct program *p;
- tmp=data->counter;
- data->counter.u.integer++;
+
decode_value2(data);
if(data->codec)
2544:
SET_ONERROR(err, do_enable_threads, 0);
#endif
+ fprintf (stderr, "Warning: Using old-style encoding\n");
+
EDB(2,fprintf(stderr, "%*sDecoding a program to <%d>: ",
- data->depth, "", data->counter.u.integer);
- print_svalue(stderr, &tmp);
+ data->depth, "", entry_id.u.integer);
+ print_svalue(stderr, &entry_id);
fputc('\n', stderr););
SETUP_DECODE_MEMOBJ(T_PROGRAM, program, p, low_allocate_program(),;);
2569:
{
placeholder=Pike_sp[-1].u.object;
if(placeholder->prog != null_program)
- Pike_error("Placeholder object is not a null_program clone!\n");
+ Pike_error("Placeholder object is not a null_program clone.\n");
dmalloc_touch_svalue(Pike_sp-1);
Pike_sp--;
- }else{
+ }
+ else if (Pike_sp[-1].type != T_INT ||
+ Pike_sp[-1].u.integer)
+ Pike_error ("Expected placeholder object or zero "
+ "from __register_new_program.\n");
+ else {
pop_stack();
}
}
3060: Inside #if defined(_REENTRANT)
UNSET_ONERROR(err);
exit_threads_disable(NULL);
#endif
- #ifdef ENCODE_DEBUG
- data->depth -= 2;
- #endif
- return;
+ goto decode_done;
}
case 2:
- tmp=data->counter;
- data->counter.u.integer++;
+
decode_value2(data);
decode_value2(data);
if(Pike_sp[-2].type==T_INT)
3082:
break;
case 3:
- tmp=data->counter;
- data->counter.u.integer++;
+
decode_value2(data);
if ((Pike_sp[-1].type == T_INT) &&
(Pike_sp[-1].u.integer < PROG_DYNAMIC_ID_START) &&
3101:
}
break;
+ case 5: { /* Forward reference for new-style encoding. */
+ struct program *p = low_allocate_program();
+
+ push_program (p);
+ 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););
+
+ #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? */
+ if (data->codec) {
+ ref_push_program (p);
+ apply (data->codec, "__register_new_program", 1);
+
+ /* Returns a placeholder. */
+ if (Pike_sp[-1].type == T_OBJECT) {
+ if (Pike_sp[-1].u.object->prog != null_program)
+ Pike_error ("Placeholder object is not a null_program clone.\n");
+ }
+ else if (Pike_sp[-1].type != T_INT ||
+ Pike_sp[-1].u.integer)
+ Pike_error ("Expected placeholder object or zero "
+ "from __register_new_program.\n");
+ pop_stack();
+ }
+ #endif
+
+ break;
+ }
+
case 4: /* New-style encoding. */
{
struct program *p;
3123:
decode_number(byteorder, data);
EDB(4,
- fprintf(stderr, "%*sByte order:%d\n",
+ fprintf(stderr, "%*sbyte order:%d\n",
data->depth, "", byteorder));
if ((byteorder != PIKE_BYTEORDER)
3145:
PROGRAM_FIXED | PROGRAM_PASS_1_DONE);
p_flags |= PROGRAM_AVOID_CHECK;
+ if (delayed_enc_val) {
+ EDB(2,fprintf(stderr, "%*sdecoding a delay encoded program: ",
+ data->depth, "");
+ print_svalue(stderr, delayed_enc_val);
+ fputc('\n', stderr););
+ if (delayed_enc_val->type != T_PROGRAM ||
+ delayed_enc_val->u.program->flags != PROGRAM_VIRGIN) {
+ decode_error (NULL, delayed_enc_val,
+ "Didn't get program embryo "
+ "for delay encoded program <%d>: ", entry_id.u.integer);
+ }
+ add_ref (p = delayed_enc_val->u.program);
+ }
+ else
+ p = NULL;
+
/* Start the new program. */
orig_compilation_depth = compilation_depth;
compilation_depth = -1;
- low_start_new_program(NULL, NULL, 0, NULL);
+ low_start_new_program(p, 1, NULL, 0, NULL);
p = Pike_compiler->new_program;
p->flags = p_flags;
3160:
debug_malloc_touch(p);
- tmp.type=T_PROGRAM;
- tmp.u.program=p;
+ if (!delayed_enc_val) {
+ struct svalue prog;
+ prog.type=T_PROGRAM;
+ prog.u.program=p;
EDB(2,fprintf(stderr, "%*sDecoding a program to <%d>: ",
- data->depth, "", data->counter.u.integer);
- print_svalue(stderr, &tmp);
+ data->depth, "", entry_id.u.integer);
+ print_svalue(stderr, &prog);
fputc('\n', stderr););
- mapping_insert(data->decoded, & data->counter, &tmp);
- tmp = data->counter;
- data->counter.u.integer++;
+ mapping_insert(data->decoded, &entry_id, &prog);
+ }
debug_malloc_touch(p);
3246:
/* Now with the linenumber info in place it gets useful to
* include the program in error messages. */
+ EDB(2,
+ fprintf(stderr, "%*sThe program is: ", data->depth, "");
+ push_program (p);
+ print_svalue (stderr, --Pike_sp);
+ fputc('\n', stderr));
+
/* identifier_index & variable_index are created by
* fixate_program() and optimize_program().
*/
3528:
ref_push_program (p);
ref_push_string (id.name);
decode_error(Pike_sp - 2, Pike_sp - 1,
- "Bad function identifier offset %d for ", no);
+ "Bad function identifier offset "
+ "(expected %d, got %d) for ", no, n);
}
add_to_identifiers(id);
3646:
p->flags |= PROGRAM_PASS_1_DONE;
- EDB(5, dump_program_tables(p, data->depth));
-
+
/* Fixate & optimize
*
* lfuns and identifier_index
3660:
compilation_depth = orig_compilation_depth;
push_program(p);
+ EDB(5, dump_program_tables(p, data->depth));
+ #ifdef PIKE_DEBUG
+ check_program (p);
+ #endif
+
/* Verify... */
#define FOO(NUMTYPE,TYPE,ARGTYPE,NAME) \
if (PIKE_CONCAT(local_num_, NAME) != p->PIKE_CONCAT(num_,NAME)) { \
3708: Inside #if defined(ENCODE_DEBUG)
#ifdef ENCODE_DEBUG
data->depth -= 2;
#endif
+ goto decode_done;
}
- break;
+
default:
Pike_error("Cannot decode program encoding type %d\n",num);
3720:
Pike_error("Failed to restore string. (Illegal type)\n");
}
- EDB(2,fprintf(stderr, "%*sDecoded to <%d>: ", data->depth, "", tmp.u.integer);
+ mapping_insert(data->decoded, &entry_id, Pike_sp-1);
+
+ decode_done:;
+ EDB(2,fprintf(stderr, "%*sDecoded to <%d>: ", data->depth, "", entry_id.u.integer);
print_svalue(stderr, Pike_sp-1);
fputc('\n', stderr););
- mapping_insert(data->decoded, & tmp, Pike_sp-1);
+
#ifdef ENCODE_DEBUG
data->depth -= 2;
#endif
3840:
{
ONERROR err;
struct decode_data *data;
+ int e;
+ struct keypair *k;
/* Attempt to avoid infinite recursion on circular structures. */
for (data = current_decode; data; data=data->next) {
3908:
(void *)data);
decode_value2(data);
+ while (data->ptr < data->len) {
+ decode_value2 (data);
+ pop_stack();
+ }
-
+ #ifdef PIKE_DEBUG
+ NEW_MAPPING_LOOP (data->decoded->data) {
+ if (k->val.type == T_PROGRAM &&
+ !(k->val.u.program->flags & PROGRAM_FINISHED)) {
+ decode_error (NULL, &k->val,
+ "Got unfinished program <%"PRINTPIKEINT"d> after decode: ",
+ k->ind.u.integer);
+ }
+ }
+ #endif
+
CALL_AND_UNSET_ONERROR(err);
return 1;
}