2003-06-02
2003-06-02 21:16:51 by Martin Stjernholm <mast@lysator.liu.se>
-
3beae43ced43b924effc871793d36459e3ecb6cd
(367 lines)
(+245/-122)
[
Show
| Annotate
]
Branch: 7.9
Improved error messages during decode.
Rev: src/encode.c:1.175
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.174 2003/06/01 18:37:19 mast Exp $
+ || $Id: encode.c,v 1.175 2003/06/02 21:16:51 mast Exp $
*/
#include "global.h"
27:
#include "bignum.h"
#include "pikecode.h"
- RCSID("$Id: encode.c,v 1.174 2003/06/01 18:37:19 mast Exp $");
+ RCSID("$Id: encode.c,v 1.175 2003/06/02 21:16:51 mast Exp $");
/* #define ENCODE_DEBUG */
450:
EDB(1,fprintf(stderr, "%*sEncoding TAG_AGAIN from <%d>\n",
data->depth, "", tmp->u.integer));
code_entry(TAG_AGAIN, tmp->u.integer, data);
- #ifdef ENCODE_DEBUG
- data->depth -= 2;
- #endif
- return;
+ goto encode_done;
}else if (val->type != T_TYPE) {
EDB(1,fprintf(stderr, "%*sEncoding to <%d>: ",
data->depth, "", data->counter.u.integer);
492: Inside #if SIZEOF_INT_TYPE > 4
Pike_error ("Cannot encode integers with more than 32 bits "
"without bignum support.\n");
#endif
- return;
+ goto encode_done;
}
else
code_entry(TAG_INT, i,data);
882:
/* Put value back in cache */
mapping_insert(data->encoded, val, &tmp);
- #ifdef ENCODE_DEBUG
- data->depth -= 2;
- #endif
- return;
+ goto encode_done;
}
}
- Pike_error("Encoding of efuns is not supported yet.\n");
+ Pike_error("Cannot encode builtin functions.\n");
}
code_entry(TAG_FUNCTION, 0, data);
940:
/* Put value back in cache */
mapping_insert(data->encoded, val, &tmp);
- #ifdef ENCODE_DEBUG
- data->depth -= 2;
- #endif
- return;
+ goto encode_done;
}
if( p->event_handler )
Pike_error("Cannot encode programs with event handlers.\n");
1457:
}
}
+ encode_done:;
+
#ifdef ENCODE_DEBUG
data->depth -= 2;
#endif
1783:
INT32 what, e, num, numh; \
DECODE("decode_number"); \
X=(what & TAG_MASK) | (num<<4); \
- EDB(5, fprintf(stderr, "%*s ==>%d\n", \
- data->depth, "", X)); \
+ EDB(5, fprintf(stderr, "%*s ==>%ld\n", \
+ data->depth, "", (long) X)); \
}while(0) \
2021:
compilation_depth = *orig_compilation_depth;
}
+ static DECLSPEC(noreturn) void decode_error (struct svalue *decoding,
+ struct svalue *other,
+ char *msg, ...)
+ ATTRIBUTE((noreturn,format (printf, 3, 4)));
+
+ static DECLSPEC(noreturn) void decode_error (struct svalue *decoding,
+ struct svalue *other,
+ char *msg, ...)
+ {
+ int n = 0;
+ char buf[4096];
+ va_list args;
+ va_start (args, msg);
+ #ifdef HAVE_VSNPRINTF
+ vsnprintf(buf, 4090, msg, args);
+ #else /* !HAVE_VSNPRINTF */
+ VSPRINTF(buf, msg, args);
+ #endif /* HAVE_VSNPRINTF */
+ va_end (args);
+
+ 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++;
+ }
+ push_text (buf); n++;
+ if (other) {
+ push_constant_text ("%O\n");
+ push_svalue (other);
+ f_sprintf (2); n++;
+ }
+ f_add (n);
+
+ f_backtrace (0);
+ f_aggregate (2);
+
+ free_svalue(& throw_value);
+ dmalloc_touch_svalue(Pike_sp-1);
+ throw_value = *--Pike_sp;
+ throw_severity = THROW_ERROR;
+ pike_throw();
+ }
+
static void decode_value2(struct decode_data *data)
#ifdef PIKE_DEBUG
2291:
break;
case 1:
- if(UNSAFE_IS_ZERO(Pike_sp-1))
+
{
-
+ int fun;
+ /* decode_value_clone_object does not call __INIT, so
+ * we want to do that ourselves...
+ */
+ struct object *o=decode_value_clone_object(Pike_sp-1);
+
+ if (!o) {
+ if (data->pickyness)
+ 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);
print_svalue(stderr, Pike_sp-1);
fputc('\n', stderr););
decode_value2(data);
- pop_stack();
- }else{
- int fun;
- struct object *o;
- /* decode_value_clone_object does not call __INIT, so
- * we want to do that ourselves...
- */
- o=decode_value_clone_object(Pike_sp-1);
+ pop_n_elems(2);
+ push_undefined();
+ break;
+ }
+
debug_malloc_touch(o);
pop_stack();
push_object(o);
2334:
ref_push_object(o);
decode_value2(data);
if(!data->codec)
- Pike_error("Failed to decode object (no codec)\n");
+ decode_error(Pike_sp - 1, NULL,
+ "Cannot decode object without codec.\n");
fun = find_identifier("decode_object", data->codec->prog);
if (fun < 0)
- Pike_error("Cannot decode objects without a "
+ decode_error(Pike_sp - 1, NULL,
+ "Cannot decode objects without a "
"\"decode_object\" function in the codec.\n");
apply_low(data->codec,fun,2);
pop_stack();
2373:
Pike_error("Object coding not compatible.\n");
break;
}
- if(Pike_sp[-1].type != T_OBJECT)
- if(data->pickyness)
- Pike_error("Failed to decode object.\n");
+
-
+ if(Pike_sp[-1].type != T_OBJECT && data->pickyness)
+ decode_error(NULL, Pike_sp - 1, "Failed to decode object. Got: ");
+
break;
}
2398:
case 1: {
struct program *p;
+ if(Pike_sp[-1].type != T_OBJECT && data->pickyness)
+ decode_error(NULL, Pike_sp - 1,
+ "Failed to decode function object. Got: ");
+
decode_value2(data);
-
+ if(Pike_sp[-1].type != T_STRING && data->pickyness)
+ decode_error(NULL, Pike_sp - 1,
+ "Failed to decode function identifier. Got: ");
+
if (Pike_sp[-2].type == T_OBJECT &&
Pike_sp[-1].type == T_STRING &&
(p = Pike_sp[-2].u.object->prog)) {
2414:
dmalloc_touch_svalue(Pike_sp-1);
break;
}
+ else if (data->pickyness) {
+ if (Pike_sp[-1].u.string->size_shift)
+ decode_error(NULL, Pike_sp - 2, "Couldn't find identifier in ");
+ else
+ decode_error(NULL, Pike_sp - 2, "Couldn't find identifier %s in ",
+ Pike_sp[-1].u.string->str);
}
-
+ }
pop_stack();
break;
}
2423:
Pike_error("Function coding not compatible.\n");
break;
}
- if(data->pickyness && Pike_sp[-1].type != T_FUNCTION)
- Pike_error("Failed to decode function.\n");
+
+ if(Pike_sp[-1].type != T_FUNCTION && data->pickyness)
+ decode_error(NULL, Pike_sp - 1, "Failed to decode function. Got: ");
+
break;
2436:
{
case 0:
{
- struct svalue *prog_code;
+
struct program *p;
tmp=data->counter;
data->counter.u.integer++;
decode_value2(data);
- /* Keep the value so that we can make a good error-message. */
- prog_code = Pike_sp-1;
- stack_dup();
-
+
if(data->codec)
{
apply(data->codec,"programof", 1);
2457:
p = program_from_svalue(Pike_sp-1);
if (!p) {
- if(data->pickyness) {
- if ((prog_code->type == T_STRING) &&
- (prog_code->u.string->len < 128) &&
- (!prog_code->u.string->size_shift)) {
- Pike_error("Failed to decode program \"%s\".\n",
- prog_code->u.string->str);
- }
- Pike_error("Failed to decode program.\n");
- }
- pop_n_elems(2);
+ if(data->pickyness)
+ decode_error(NULL, Pike_sp - 1,
+ "Failed to decode program. Got: ");
+ pop_stack();
push_undefined();
break;
}
- /* Remove the extra entry from the stack. */
- ref_push_program(p);
- stack_pop_2_elems_keep_top();
+
+ add_ref(p);
+ pop_stack();
+ push_program(p);
break;
}
- case 1:
+ case 1: /* Old-style encoding. */
{
int d, in;
size_t size=0;
2534:
Pike_error("Cannot decode programs encoded with other pike version.\n");
pop_n_elems(2);
+ data->pickyness++;
+
debug_malloc_touch(p);
decode_number(p->flags,data);
2570:
p->parent=program_from_svalue(Pike_sp-1);
break;
default:
- Pike_error("Program decode failed!\n");
+ decode_error(NULL, Pike_sp - 1, "Program decode failed. Got: ");
}
if(p->parent) {
add_ref(p->parent);
2634:
getdata2(p->linenumbers, p->num_linenumbers);
+ /* Now with the linenumber info in place it gets useful to
+ * include the program in error messages. */
+
#ifdef DEBUG_MALLOC
if(p->num_linenumbers && p->linenumbers &&
EXTRACT_UCHAR(p->linenumbers)==127)
2657:
if(p->identifier_index[d] > p->num_identifier_references)
{
p->identifier_index[d]=0;
- Pike_error("Malformed program in decode.\n");
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, NULL, "Malformed program in decode.\n");
}
}
2668:
if(p->variable_index[d] > p->num_identifiers)
{
p->variable_index[d]=0;
- Pike_error("Malformed program in decode.\n");
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, NULL, "Malformed program in decode.\n");
}
}
2679:
if(p->identifier_references[d].inherit_offset > p->num_inherits)
{
p->identifier_references[d].inherit_offset=0;
- Pike_error("Malformed program in decode.\n");
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, NULL, "Malformed program in decode.\n");
}
decode_number(p->identifier_references[d].identifier_offset,data);
decode_number(p->identifier_references[d].id_flags,data);
2698:
debug_malloc_touch(p);
debug_malloc_touch(dat);
- data->pickyness++;
-
-
+
/* p->inherits[0].prog=p;
p->inherits[0].parent_offset=1;
*/
2710:
if(placeholder->prog != null_program)
{
debug_malloc_touch(placeholder);
- Pike_error("Placeholder argument is not a null_program clone!");
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, NULL,
+ "Placeholder argument is not a null_program clone.\n");
}else{
free_program(placeholder->prog);
add_ref(placeholder->prog = p);
2733:
if(d==0)
{
if(Pike_sp[-1].type != T_PROGRAM ||
- Pike_sp[-1].u.program != p)
- Pike_error("Program decode failed!\n");
+ Pike_sp[-1].u.program != p) {
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, Pike_sp - 2,
+ "Program decode of self inherit failed. Got: ");
+ }
sub_ref(p);
}
2755:
switch(Pike_sp[-1].type)
{
- case T_FUNCTION:
- if(Pike_sp[-1].subtype == FUNCTION_BUILTIN)
- Pike_error("Failed to decode parent.\n");
+ case T_PROGRAM:
+ EDB(3, fprintf(stderr,"INHERIT%x = prog\n",p->id); );
+ p->inherits[d].prog=Pike_sp[-1].u.program;
+ Pike_sp--;
+ dmalloc_touch_svalue(Pike_sp);
+ break;
-
+ case T_FUNCTION:
+ if(Pike_sp[-1].subtype != FUNCTION_BUILTIN) {
EDB(3, fprintf(stderr,"INHERIT%x = func { %p, %d} \n",p->id,Pike_sp[-1].u.object, Pike_sp[-1].subtype); );
p->inherits[d].parent_identifier=Pike_sp[-1].subtype;
p->inherits[d].prog=program_from_svalue(Pike_sp-1);
- if(!p->inherits[d].prog)
- Pike_error("Failed to decode parent.\n");
+ if(!p->inherits[d].prog) {
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, Pike_sp - 2,
+ "Failed to decode inherited program. Got: ");
+ }
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 */
- case T_PROGRAM:
- EDB(3, fprintf(stderr,"INHERIT%x = prog\n",p->id); );
- p->inherits[d].prog=Pike_sp[-1].u.program;
- Pike_sp--;
- dmalloc_touch_svalue(Pike_sp);
- break;
+
default:
- Pike_error("Failed to decode inheritance.\n");
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, Pike_sp - 2,
+ "Failed to decode inherited program. Got: ");
}
p->num_inherits=d+1;
2809:
{
decode_number(p->identifiers[d].func.offset,data);
} else {
- Pike_error("Cannot decode functions implemented in C "
- "(identifier='%s').\n",
- p->identifiers[d].name->str);
+ ref_push_program (p);
+ ref_push_string (p->identifiers[d].name);
+ decode_error(Pike_sp - 1, Pike_sp - 2,
+ "Cannot decode function implemented in C: ");
}
}
2864:
if(placeholder && data->pass == 1)
{
- if(!p || (placeholder->storage))
+ if(placeholder->storage)
{
- Pike_error("Placeholder already has storage!\n");
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, NULL, "Placeholder already has storage!\n");
} else {
placeholder->storage=p->storage_needed ?
(char *)xalloc(p->storage_needed) :
3006:
}else{
f_arrow(2);
}
- if(data->pickyness && Pike_sp[-1].type != T_PROGRAM)
- Pike_error("Failed to decode program.\n");
+ if(Pike_sp[-1].type != T_PROGRAM && data->pickyness)
+ decode_error(NULL, Pike_sp - 1, "Failed to decode program. Got: ");
break;
case 3:
3019:
(Pike_sp[-1].u.integer > 0)) {
struct program *p = id_to_program(Pike_sp[-1].u.integer);
if (!p) {
- Pike_error("Failed to decode program %"PRINTPIKEINT"d\n",
+ Pike_error("Failed to get program from ID %"PRINTPIKEINT"d\n",
Pike_sp[-1].u.integer);
}
pop_stack();
ref_push_program(p);
} else {
- Pike_error("Failed to decode program.\n");
+ decode_error(NULL, Pike_sp - 1,
+ "Failed to decode program by ID. Expected integer, got: ");
}
break;
- case 4:
+ case 4: /* New-style encoding. */
{
struct program *p;
ONERROR err;
3171:
add_to_linenumbers(lineno_info);
}
+ /* Now with the linenumber info in place it gets useful to
+ * include the program in error messages. */
+
/* identifier_index & variable_index are created by
* fixate_program() and optimize_program().
*/
3179:
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");
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, Pike_sp - 2,
+ "Nonstrings in string table: ");
}
add_to_strings(Pike_sp[-1].u.string);
dmalloc_touch_svalue(Pike_sp-1);
3236:
if (no > p->num_identifier_references) {
EDB (3, dump_program_tables (p, data->depth));
- Pike_error("Bad identifier reference offset: %d != %d\n", no,
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, NULL,
+ "Bad identifier reference offset: %d != %d\n", no,
Pike_compiler->new_program->
num_identifier_references);
} else if (no == p->num_identifier_references) {
3255:
/* name */
decode_value2(data);
if (Pike_sp[-1].type != T_STRING) {
- Pike_error("Bad variable name (not a string)\n");
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, Pike_sp - 2,
+ "Bad variable name (not a string): ");
}
/* type */
decode_value2(data);
if (Pike_sp[-1].type != T_TYPE) {
- Pike_error("Bad variable type (not a type)\n");
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, Pike_sp - 2,
+ "Bad variable type (not a type): ");
}
/* Expected identifier offset */
3281:
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);
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, NULL,
+ "Bad variable identifier offset: %d\n", no);
}
pop_n_elems(2);
3298:
/* name */
decode_value2(data);
if (Pike_sp[-1].type != T_STRING) {
- Pike_error("Bad function name (not a string)\n");
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, Pike_sp - 2,
+ "Bad function name (not a string): ");
}
/* type */
decode_value2(data);
if (Pike_sp[-1].type != T_TYPE) {
- Pike_error("Bad function type (not a type)\n");
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, Pike_sp - 2,
+ "Bad function type (not a type): ");
}
/* func_flags (aka identifier_flags) */
3352:
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);
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, NULL,
+ "Bad function identifier offset: %d\n", no);
}
pop_n_elems(2);
3368:
/* name */
decode_value2(data);
if (Pike_sp[-1].type != T_STRING) {
- Pike_error("Bad function name (not a string)\n");
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, Pike_sp - 2,
+ "Bad constant name (not a string): ");
}
id.name = Pike_sp[-1].u.string;
3385:
/* type */
decode_value2(data);
if (Pike_sp[-1].type != T_TYPE) {
- Pike_error("Bad function type (not a type)\n");
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, Pike_sp - 2,
+ "Bad constant type (not a type): ");
}
id.type = Pike_sp[-1].u.type;
3430:
}
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);
+ ref_push_program (p);
+ ref_push_string (id.name);
+ decode_error(Pike_sp - 2, Pike_sp - 1,
+ "Bad function identifier offset %d for ", no);
}
add_to_identifiers(id);
3455:
decode_number(no, data);
if (no !=
Pike_compiler->new_program->num_identifier_references) {
- Pike_error("Bad inherit identifier offset: %d\n", no);
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, NULL,
+ "Bad inherit identifier offset: %d\n", no);
}
/* name */
3464:
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");
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, Pike_sp - 2,
+ "Bad inherit name (not a string): ");
}
/* 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));
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, Pike_sp - 2,
+ "Bad inherit: Expected program, got ");
}
prog = Pike_sp[-1].u.program;
-
+ if (prog == placeholder_program) {
+ ref_push_program (p);
+ decode_error (Pike_sp - 1, NULL,
+ "Trying to inherit placeholder program "
+ "(resolver or codec problem).\n");
+ }
+ if(!(prog->flags & (PROGRAM_FINISHED | PROGRAM_PASS_1_DONE))) {
+ ref_push_program (p);
+ decode_error (Pike_sp - 1, Pike_sp - 2,
+ "Cannot inherit a program which is not "
+ "fully compiled yet (resolver or codec problem):\n");
+ }
/* parent */
decode_value2(data);
3481:
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");
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, Pike_sp - 2,
+ "Bad inherit: Parent isn't an object: ");
}
/* parent_identifier */
3494:
decode_number(no, data);
if (prog->num_identifier_references != no) {
- Pike_error("Bad number of identifiers in inherit: %d\n", no);
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, NULL,
+ "Bad number of identifiers in inherit: %d != %d\n",
+ no, prog->num_identifier_references);
}
EDB(5,
3536:
*
* lfuns and identifier_index
*/
+ ref_push_program (p);
if (!(p = end_first_pass(2))) {
- Pike_error("Failed to decode program.\n");
+ decode_error(Pike_sp - 1, NULL, "Failed to decode program.\n");
}
-
+ pop_stack();
compilation_depth = orig_compilation_depth;
push_program(p);
/* Verify... */
- #define FOO(NUMTYPE,TYPE,ARGTYPE,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)); \
+ #define FOO(NUMTYPE,TYPE,ARGTYPE,NAME) \
+ if (PIKE_CONCAT(local_num_, NAME) != p->PIKE_CONCAT(num_,NAME)) { \
+ ref_push_program (p); \
+ decode_error(Pike_sp - 1, NULL, \
+ "Value mismatch for num_" TOSTR(NAME) ": %d != %d\n", \
+ PIKE_CONCAT(local_num_, NAME), \
+ p->PIKE_CONCAT(num_, NAME)); \
}
#include "program_areas.h"
3567:
!Pike_sp[-1].u.integer) {
constant->name = NULL;
} else {
- Pike_error("Name of constant is not a string.\n");
+ ref_push_program (p);
+ decode_error(Pike_sp - 1, Pike_sp - 2,
+ "Name of constant is not a string: ");
}
constant->sval = Pike_sp[-2];
dmalloc_touch_svalue(Pike_sp-1);