2002-05-10
2002-05-10 16:10:26 by Henrik Grubbström (Grubba) <grubba@grubba.org>
-
91829110b93d507748fa7bc8fc43538f4d83d7ee
(960 lines)
(+947/-13)
[
Show
| Annotate
]
Branch: 7.9
Ported new program encoder from Pike 7.2. Still disabled though.
Rev: src/encode.c:1.143
26:
#include "bignum.h"
#include "pikecode.h"
- RCSID("$Id: encode.c,v 1.142 2002/05/09 15:33:31 mast Exp $");
+ RCSID("$Id: encode.c,v 1.143 2002/05/10 16:10:26 grubba Exp $");
/* #define ENCODE_DEBUG */
-
+ /* Use the old encoding method for programs. */
+ #define OLD_PIKE_ENCODE_PROGRAM
+
#ifdef ENCODE_DEBUG
/* Pass a nonzero integer as the third arg to encode_value,
* encode_value_canonic and decode_value to activate this debug. */
106:
#define MAX_SMALL (1<<(8-SIZE_SHIFT))
#define COUNTER_START -MAX_SMALL
+ /* Entries used to encode the identifier_references table. */
+ #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
+
struct encode_data
{
int canonic;
239:
static void code_number(ptrdiff_t num, struct encode_data *data)
{
+ EDB(5, fprintf(stderr, "%*scode_number(%d)\n",
+ data->depth, "", num));
code_entry(DO_NOT_WARN(num & 15),
num >> 4, data);
}
566:
*
* (Is too, --with-long-long-int. /Mirar)
*/
+ /* FIXME: Doesn't encode NUMBER_UNDEFINED et al. */
code_entry(TAG_INT, val->u.integer,data);
break;
1016:
Pike_error("Cannot encode programs with event handlers.\n");
Pike_error("Cannot encode C programs.\n");
}
- /*FIXME: save p->parent!! */
+
+
+ EDB(1,
+ fprintf(stderr, "%*sencode: encoding program\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);
pop_stack();
code_number(p->flags,data);
code_number(p->storage_needed,data);
- code_number(p->xstorage,data);
- code_number(p->parent_info_storage,data);
+ code_number(p->xstorage,data); /**/
+ code_number(p->parent_info_storage,data); /**/
code_number(p->alignment_needed,data);
code_number(p->timestamp.tv_sec,data);
1034:
ref_push_program(p->parent);
else
push_int(0);
- encode_value2(Pike_sp-1,data);
+ encode_value2(Pike_sp-1,data); /**/
pop_stack();
#define FOO(X,Y,Z) \
1063:
#else /* !ENCODE_PROGRAM */
adddata2(p->program, p->num_program);
#endif /* ENCODE_PROGRAM */
- #ifdef PIKE_USE_MACHINE_CODE
+
adddata2(p->relocations, p->num_relocations);
- #endif /* PIKE_USE_MACHINE_CODE */
+
adddata2(p->linenumbers, p->num_linenumbers);
1145:
encode_value2(& p->constants[d].sval, data);
adddata3(p->constants[d].name);
}
+
+ #else /* !OLD_PIKE_ENCODE_PROGRAM */
+
+ /* Type 4 -- Portable encoding. */
+ code_entry(type_to_tag(val->type), 4, data);
+
+ /* Byte-order. */
+ code_number(PIKE_BYTEORDER, data);
+
+ /* flags */
+ code_number(p->flags,data);
+
+ /* version */
+ f_version(0);
+ encode_value2(Pike_sp-1, data);
+ pop_stack();
+
+ /* parent */
+ if (p->parent) {
+ ref_push_program(p->parent);
+ } else {
+ push_int(0);
+ }
+ encode_value2(Pike_sp-1, data);
+ pop_stack();
+
+ /* num_* */
+ #define FOO(X,Y,Z) \
+ code_number( p->PIKE_CONCAT(num_,Z), data);
+ #include "program_areas.h"
+
+ /* Byte-code method
+ */
+ code_number(PIKE_BYTECODE_METHOD, data);
+
+ /* 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) {
+ fatal("ENCODE_PROGRAM() failed:\n"
+ "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);
+
+ {
+ struct svalue str_sval;
+ str_sval.type = T_STRING;
+ str_sval.subtype = 0;
+ /* strings */
+ for(d=0;d<p->num_strings;d++) {
+ str_sval.u.string = p->strings[d];
+ encode_value2(&str_sval, data);
+ }
+ }
+
+ EDB(5, dump_program_tables(p, data->depth));
+
+ /* Dump the identifiers in a portable manner... */
+ {
+ int inherit_num = 1;
+ struct svalue str_sval;
+ char *id_dumped = (char *) alloca(p->num_identifiers);
+ MEMSET(id_dumped,0,p->num_identifiers);
+ str_sval.type = T_STRING;
+ str_sval.subtype = 0;
+
+ 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;
+ }
+
+ /* 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. */
+ if (ref->id_flags & ID_INHERITED) continue;
+
+ 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;
+ int i;
+ 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 {
+ 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;
+
+ if (IDENTIFIER_IS_CONSTANT(id->identifier_flags)) {
+ /* Constant */
+
+ EDB(3,
+ fprintf(stderr, "%*sencode: encoding constant\n",
+ data->depth, ""));
+
+ code_number(ID_ENTRY_CONSTANT, data);
+ code_number(ref->id_flags, data);
+
+ /* name */
+ str_sval.u.string = id->name;
+ encode_value2(&str_sval, data);
+
+ /* offset */
+ code_number(id->func.offset, data);
+
+ /* type */
+ ref_push_type_value(id->type);
+ encode_value2(Pike_sp-1, data);
+ pop_stack();
+
+ /* run-time type */
+ code_number(id->run_time_type, data);
+ } else if (IDENTIFIER_IS_PIKE_FUNCTION(id->identifier_flags)) {
+ /* Pike function */
+
+ EDB(3,
+ fprintf(stderr, "%*sencode: encoding function\n",
+ data->depth, ""));
+
+ code_number(ID_ENTRY_FUNCTION, data);
+ code_number(ref->id_flags, data);
+
+ /* name */
+ str_sval.u.string = id->name;
+ encode_value2(&str_sval, data);
+
+ /* type */
+ ref_push_type_value(id->type);
+ encode_value2(Pike_sp-1, data);
+ pop_stack();
+
+ /* func_flags (aka identifier_flags) */
+ code_number(id->identifier_flags, data);
+
+ /* func */
+ code_number(id->func.offset, data);
+
+ /* opt_flags */
+ code_number(id->opt_flags, data);
+ } else if (id->identifier_flags & IDENTIFIER_C_FUNCTION) {
+ /* C Function */
+ /* Not supported. */
+ Pike_error("Cannot encode functions implemented in C "
+ "(identifier='%s').\n",
+ p->identifiers[d].name->str);
+ } else {
+ /* Variable */
+ EDB(3,
+ fprintf(stderr, "%*sencode: encoding variable\n",
+ data->depth, ""));
+
+ code_number(ID_ENTRY_VARIABLE, data);
+ code_number(ref->id_flags, data);
+
+ /* name */
+ str_sval.u.string = id->name;
+ encode_value2(&str_sval, data);
+
+ /* type */
+ ref_push_type_value(id->type);
+ encode_value2(Pike_sp-1, data);
+ pop_stack();
+ }
+ }
+
+ /* 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 */
+ INT16 inherit_flags_change = 0;
+ struct inherit *inh = p->inherits + inherit_num;
+ struct reference *ref = p->identifier_references + d;
+ int i;
+
+ 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++) {
+ /* Ignore overloaded identifiers. */
+ if (ref[i].inherit_offset) {
+ inherit_flags_change |= ref[i].id_flags ^
+ inh->prog->identifier_references[i].id_flags;
+ }
+ }
+ EDB(5,
+ fprintf(stderr, "%*sraw inherit_flags: %04x\n",
+ data->depth, "", inherit_flags_change));
+ inherit_flags_change &= ~(ID_HIDDEN|ID_INHERITED);
+ code_number(inherit_flags_change, data);
+
+ EDB(5,
+ fprintf(stderr, "%*sinherit_flags: %04x\n",
+ data->depth, "", inherit_flags_change));
+
+ /* Identifier reference level at insertion. */
+ code_number(d_max, data);
+
+ /* name */
+ str_sval.u.string = inh->name;
+ encode_value2(&str_sval, data);
+
+ /* prog */
+ ref_push_program(inh->prog);
+ encode_value2(Pike_sp-1, data);
+ pop_stack();
+
+ /* parent */
+ if (inh->parent) {
+ ref_push_object(inh->parent);
+ } else {
+ push_int(0);
+ }
+ encode_value2(Pike_sp-1, data);
+ 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;
+ str_sval.type = T_STRING;
+ str_sval.subtype = 0;
+
+ /* constants */
+ for(d=0;d<p->num_constants;d++)
+ {
+ /* value */
+ encode_value2(&p->constants[d].sval, data);
+
+ /* name */
+ if (p->constants[d].name) {
+ str_sval.u.string = p->constants[d].name;
+ encode_value2(&str_sval, data);
+ } else {
+ push_int(0);
+ encode_value2(Pike_sp-1, data);
+ Pike_sp--;
+ }
+ }
+ }
+ #endif /* OLD_PIKE_ENCODE_PROGRAM */
}else{
code_entry(TAG_PROGRAM, 0, data);
encode_value2(Pike_sp-1, data);
1479:
INT32 what, e, num, numh; \
DECODE("decode_number"); \
X=(what & TAG_MASK) | (num<<4); \
+ EDB(5, fprintf(stderr, "%*s ==>%d\n", \
+ data->depth, "", X)); \
}while(0) \
1783: Inside #if defined(ENCODE_DEBUG)
data->depth, "", num);
else
- if(data->debug < 2)
+ if(data->debug > 1)
fprintf(stderr, "%*sDecoding to <%d>: TAG%d (%d)\n",
data->depth, "", data->counter.u.integer ,
what & TAG_MASK, num);
1928:
{
struct mapping *m;
if(num<0)
- Pike_error("Failed to decode string. (mapping size is negative)\n");
+ Pike_error("Failed to decode mapping. (mapping size is negative)\n");
/* Heruetical */
if(data->ptr + num > data->len)
1958:
struct multiset *m;
struct array *a;
if(num<0)
- Pike_error("Failed to decode string. (multiset size is negative)\n");
+ Pike_error("Failed to decode multiset. (multiset size is negative)\n");
/* Heruetical */
if(data->ptr + num > data->len)
2067:
ref_push_object(o);
decode_value2(data);
if(!data->codec)
- Pike_error("Failed to decode (no codec)\n");
+ Pike_error("Failed to decode object (no codec)\n");
fun = find_identifier("decode_object", data->codec->prog);
if (fun < 0)
2161:
case TAG_PROGRAM:
+ EDB(3,
+ fprintf(stderr, "%*s TAG_PROGRAM(%d)\n",
+ data->depth, "", num));
switch(num)
{
case 0:
2202:
pop_stack();
break;
}
+
case 1:
{
int d, in;
2348:
}
getdata2(p->program, p->num_program);
- #ifdef PIKE_USE_MACHINE_CODE
+
getdata2(p->relocations, p->num_relocations);
- #endif /* PIKE_USE_MACHINE_CODE */
+
#ifdef DECODE_PROGRAM
DECODE_PROGRAM(p);
2750:
}
break;
+ case 4:
+ {
+ struct program *p;
+ ONERROR err;
+ int byteorder;
+ int bytecode_method;
+ int entry_type;
+ INT16 id_flags;
+ INT16 p_flags;
+ #define FOO(NUMTYPE,Y,NAME) \
+ 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,
+ fprintf(stderr, "%*sByte order:%d\n",
+ data->depth, "", byteorder));
+
+ if ((byteorder != PIKE_BYTEORDER)
+ #if (PIKE_BYTEORDER == 1234)
+ && (byteorder != 4321)
+ #else
+ #if (PIKE_BYTEORDER == 4321)
+ && (byteorder != 1234)
+ #endif
+ #endif
+ ) {
+ Pike_error("Unsupported byte-order. Native:%d Encoded:%d\n",
+ PIKE_BYTEORDER, byteorder);
+ }
+
+ /* Decode flags. */
+ decode_number(p_flags,data);
+ p_flags &= ~(PROGRAM_FINISHED | PROGRAM_OPTIMIZED |
+ PROGRAM_FIXED | PROGRAM_PASS_1_DONE);
+ p_flags |= PROGRAM_AVOID_CHECK;
+
+ /* Start the new program. */
+ low_start_new_program(NULL, NULL, 0, NULL);
+ p = Pike_compiler->new_program;
+
+ p->flags = p_flags;
+
+ /* Kludge to get end_first_pass() to free the program. */
+ Pike_compiler->num_parse_error++;
+
+ SET_ONERROR(err, end_first_pass, 0);
+
+ debug_malloc_touch(p);
+
+ tmp.type=T_PROGRAM;
+ tmp.u.program=p;
+ EDB(2,fprintf(stderr, "%*sDecoding a program to <%d>: ",
+ data->depth, "", data->counter.u.integer);
+ print_svalue(stderr, &tmp);
+ fputc('\n', stderr););
+ mapping_insert(data->decoded, & data->counter, &tmp);
+ tmp = data->counter;
+ data->counter.u.integer++;
+
+ debug_malloc_touch(p);
+
+ /* Check the version. */
+ decode_value2(data);
+ f_version(0);
+ if(!is_eq(Pike_sp-1,Pike_sp-2))
+ Pike_error("Cannot decode programs encoded with other pike version.\n");
+ pop_n_elems(2);
+
+ debug_malloc_touch(p);
+
+ /* parent */
+ decode_value2(data);
+ if (Pike_sp[-1].type == T_PROGRAM) {
+ p->parent = Pike_sp[-1].u.program;
+ } else if ((Pike_sp[-1].type == T_INT) &&
+ (!Pike_sp[-1].u.integer)) {
+ p->parent = NULL;
+ } else {
+ Pike_error("Bad type for parent program (%s)\n",
+ get_name_of_type(Pike_sp[-1].type));
+ }
+ Pike_sp--;
+
+ /* Decode lengths. */
+ #define FOO(X,Y,NAME) decode_number(PIKE_CONCAT(local_num_, NAME), data);
+ #include "program_areas.h"
+
+ /* Byte-code method */
+ decode_number(bytecode_method, data);
+ if (bytecode_method != PIKE_BYTECODE_METHOD) {
+ Pike_error("Unsupported byte-code method: %d\n", bytecode_method);
+ }
+
+ /* Decode program */
+ if (data->ptr + (int)local_num_program >= data->len) {
+ Pike_error("Failed to decode program. (string too short)\n");
+ }
+ for (e=0; e<(int)local_num_program; e++) {
+ PIKE_OPCODE_T opcode;
+ MEMCPY(&opcode, data->data + data->ptr, sizeof(PIKE_OPCODE_T));
+ data->ptr += sizeof(PIKE_OPCODE_T);
+ add_to_program(opcode);
+ }
+
+ /* Decode relocations */
+ for (e=0; e<(int)local_num_relocations; e++) {
+ size_t reloc;
+ decode_number(reloc, data);
+ CHECK_RELOC(reloc, local_num_program);
+ add_to_relocations(reloc);
+ }
+
+ /* Perform relocation. */
+ #ifdef DECODE_PROGRAM
+ DECODE_PROGRAM(p);
+ #endif /* DECODE_PROGRAM */
+ make_program_executable(p);
+
+ /* Decode linenumbers */
+ if (data->ptr + (int)local_num_linenumbers >= data->len) {
+ Pike_error("Failed to decode linenumbers. (string too short)\n");
+ }
+ for (e=0; e<(int)local_num_linenumbers; e++) {
+ char lineno_info;
+ lineno_info = *(data->data + data->ptr++);
+ add_to_linenumbers(lineno_info);
+ }
+
+ /* identifier_index & variable_index are created by
+ * fixate_program() and optimize_program().
+ */
+
+ /* Decode strings */
+ for (e=0; e<local_num_strings; e++) {
+ decode_value2(data);
+ if (Pike_sp[-1].type != T_STRING) {
+ Pike_error("Non strings in string table.\n");
+ }
+ add_to_strings(Pike_sp[-1].u.string);
+ Pike_sp--;
+ }
+
+ /* Place holder constants.
+ *
+ * These will be replaced later on.
+ */
+ {
+ struct program_constant constant;
+ constant.name = NULL;
+ constant.sval.type = T_INT;
+ constant.sval.subtype = NUMBER_UNDEFINED;
+ constant.sval.u.integer = 0;
+
+ 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
+ while (entry_type != ID_ENTRY_EOT) {
+ decode_number(id_flags, data);
+ 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);
+ ref.identifier_offset = p->inherits[ref.inherit_offset].prog->
+ identifier_references[ref_no].identifier_offset;
+
+ /* Expected identifier reference number */
+ decode_number(no, data);
+
+ if (no > p->num_identifier_references) {
+ EDB (3, dump_program_tables (p, data->depth));
+ Pike_error("Bad identifier reference offset: %d != %d\n", no,
+ Pike_compiler->new_program->
+ num_identifier_references);
+ } else if (no == p->num_identifier_references) {
+ add_to_identifier_references(ref);
+ }
+ else {
+ p->identifier_references[no] = ref;
+ }
+ }
+ break;
+
+ case ID_ENTRY_VARIABLE:
+ {
+ int no;
+
+ /* name */
+ decode_value2(data);
+ if (Pike_sp[-1].type != T_STRING) {
+ Pike_error("Bad variable name (not a string)\n");
+ }
+
+ /* type */
+ decode_value2(data);
+ if (Pike_sp[-1].type != T_TYPE) {
+ Pike_error("Bad variable type (not a type)\n");
+ }
+
+ /* 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
+ */
+ if (no != define_variable(Pike_sp[-2].u.string,
+ Pike_sp[-1].u.type,
+ id_flags)) {
+ Pike_error("Bad variable identifier offset: %d\n", no);
+ }
+
+ pop_n_elems(2);
+ }
+ break;
+ case ID_ENTRY_FUNCTION:
+ {
+ union idptr func;
+ unsigned INT8 func_flags;
+ unsigned INT16 opt_flags;
+ int no;
+ int n;
+
+ /* name */
+ decode_value2(data);
+ if (Pike_sp[-1].type != T_STRING) {
+ Pike_error("Bad function name (not a string)\n");
+ }
+
+ /* type */
+ decode_value2(data);
+ if (Pike_sp[-1].type != T_TYPE) {
+ Pike_error("Bad function type (not a type)\n");
+ }
+
+ /* func_flags (aka identifier_flags) */
+ decode_number(func_flags, data);
+
+ /* func */
+ decode_number(func.offset, data);
+
+ /* 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, {
+ INT32 line;
+ 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"
+ "%*s @ %s:%d\n",
+ data->depth, "",
+ Pike_sp[-2].u.string->str, id_flags, func_flags,
+ data->depth, "",
+ func.offset, opt_flags,
+ data->depth, "",
+ file->str, line);
+ });
+
+ /* Alters
+ *
+ * identifiers, identifier_references
+ */
+ n = define_function(Pike_sp[-2].u.string,
+ Pike_sp[-1].u.type,
+ id_flags, func_flags,
+ &func, opt_flags);
+ if (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)) {
+ Pike_error("Bad function identifier offset: %d\n", no);
+ }
+
+ pop_n_elems(2);
+ }
+ break;
+ case ID_ENTRY_CONSTANT:
+ {
+ struct identifier id;
+ struct reference ref;
+ int no;
+ int n;
+
+ /* name */
+ decode_value2(data);
+ if (Pike_sp[-1].type != T_STRING) {
+ Pike_error("Bad function name (not a string)\n");
+ }
+ id.name = Pike_sp[-1].u.string;
+
+ /* identifier_flags */
+ id.identifier_flags = IDENTIFIER_CONSTANT;
+
+ /* offset */
+ decode_number(id.func.offset, data);
+
+ /* FIXME:
+ * Verify validity of func.offset
+ */
+
+ /* type */
+ decode_value2(data);
+ if (Pike_sp[-1].type != T_TYPE) {
+ Pike_error("Bad function type (not a type)\n");
+ }
+ id.type = Pike_sp[-1].u.type;
+
+ /* run_time_type */
+ decode_number(id.run_time_type, data);
+
+ /* Expected identifier number. */
+ decode_number(no, data);
+
+ n = isidentifier(id.name);
+
+ #ifdef PROFILING
+ id.self_time=0;
+ id.num_calls=0;
+ id.total_time=0;
+ #endif
+
+ /* id_flags */
+ ref.id_flags = id_flags;
+
+ /* identifier_offset */
+ ref.identifier_offset =
+ Pike_compiler->new_program->num_identifiers;
+
+ /* ref.inherit_offset */
+ ref.inherit_offset = 0;
+
+ EDB(5,
+ fprintf(stderr,
+ "%*sdefining constant(\"%s\", X, 0x%04x)\n",
+ data->depth, "",
+ Pike_sp[-2].u.string->str, id_flags));
+
+ /* Alters
+ *
+ * identifiers, identifier_references
+ */
+
+ if (n < 0 || (n = override_identifier (&ref, id.name, 0)) < 0) {
+ n = p->num_identifier_references;
+ add_to_identifier_references(ref);
+ }
+
+ if (no != n) {
+ if (id.name->size_shift)
+ Pike_error("Bad constant identifier offset: %d\n", no);
+ else
+ Pike_error("Bad constant identifier offset %d for %s\n",
+ no, id.name->str);
+ }
+
+ add_to_identifiers(id);
+ Pike_sp -= 2;
+ }
+ break;
+ 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) {
+ Pike_error("Bad inherit identifier offset: %d\n", no);
+ }
+
+ /* name */
+ decode_value2(data);
+ if (Pike_sp[-1].type == T_STRING) {
+ name = Pike_sp[-1].u.string;
+ } else if ((Pike_sp[-1].type != T_INT) ||
+ Pike_sp[-1].u.integer) {
+ Pike_error("Bad function name (not a string)\n");
+ }
+
+ /* prog */
+ decode_value2(data);
+ if (Pike_sp[-1].type != T_PROGRAM) {
+ Pike_error("Bad inherit: Expected program, got %s\n",
+ get_name_of_type(Pike_sp[-1].type));
+ }
+ prog = Pike_sp[-1].u.program;
+
+ /* parent */
+ decode_value2(data);
+ if (Pike_sp[-1].type == T_OBJECT) {
+ parent = Pike_sp[-1].u.object;
+ } else if ((Pike_sp[-1].type != T_INT) ||
+ Pike_sp[-1].u.integer) {
+ Pike_error("Bad inherit: Parent isn't an object.\n");
+ }
+
+ /* 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) {
+ Pike_error("Bad number of identifiers in inherit: %d\n", no);
+ }
+
+ EDB(5,
+ fprintf(stderr,
+ "%*slow_inherit(..., \"%s\")\n",
+ data->depth, "",
+ name?name->str:"NULL"));
+
+ /* Alters
+ *
+ * storage, inherits and identifier_references
+ */
+ low_inherit(prog, parent, parent_identifier,
+ parent_offset + 42, id_flags, name);
+
+ pop_n_elems(3);
+ }
+ break;
default:
-
+ Pike_error("Unsupported id entry type: %d\n", entry_type);
+ }
+ decode_number(entry_type, data);
+ }
+
+ #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;
+
+ EDB(5, dump_program_tables(p, data->depth));
+
+ /* Fixate & optimize
+ *
+ * lfuns and identifier_index
+ */
+ if (!(p = end_first_pass(2))) {
+ Pike_error("Failed to decode program.\n");
+ }
+ push_program(p);
+
+ /* Verify... */
+ #define FOO(NUMTYPE,Y,NAME) \
+ if (PIKE_CONCAT(local_num_, NAME) != p->PIKE_CONCAT(num_,NAME)) { \
+ Pike_error("Value mismatch for num_" TOSTR(NAME) ": %d != %d\n", \
+ PIKE_CONCAT(local_num_, NAME), \
+ p->PIKE_CONCAT(num_, NAME)); \
+ }
+ #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;
+ /* value */
+ decode_value2(data);
+ /* name */
+ decode_value2(data);
+ if (Pike_sp[-1].type == T_STRING) {
+ constant->name = Pike_sp[-1].u.string;
+ } else if ((Pike_sp[-1].type == T_INT) &&
+ !Pike_sp[-1].u.integer) {
+ constant->name = NULL;
+ } else {
+ Pike_error("Name of constant is not a string.\n");
+ }
+ constant->sval = Pike_sp[-2];
+ Pike_sp -= 2;
+ }
+
+ /* The program should be consistent now. */
+ p->flags &= ~PROGRAM_AVOID_CHECK;
+
+ EDB(5, fprintf(stderr, "%*sProgram flags: 0x%04x\n",
+ data->depth, "", p->flags));
+
+ #ifdef ENCODE_DEBUG
+ data->depth -= 2;
+ #endif
+ }
+ break;
+
+ default:
Pike_error("Cannot decode program encoding type %d\n",num);
}
break;