pike.git / src / encode.c

version» Context lines:

pike.git/src/encode.c:1:   /*   || 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.181 2004/05/11 15:18:53 grubba Exp $ + || $Id: encode.c,v 1.182 2004/05/11 15:42:50 grubba Exp $   */      #include "global.h"   #include "stralloc.h"   #include "pike_macros.h"   #include "object.h"   #include "constants.h"   #include "interpret.h"   #include "svalue.h"   #include "mapping.h"
pike.git/src/encode.c:25:   #include "fsort.h"   #include "threads.h"   #include "stuff.h"   #include "version.h"   #include "bignum.h"   #include "pikecode.h"   #include "pike_types.h"   #include "opcodes.h"   #include "peep.h"    - RCSID("$Id: encode.c,v 1.181 2004/05/11 15:18:53 grubba Exp $"); + RCSID("$Id: encode.c,v 1.182 2004/05/11 15:42:50 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. */   #define EDB(N,X) do { debug_malloc_touch(data); if (data->debug>=N) {X;} } while (0)
pike.git/src/encode.c:1188:    encode_value2(Pike_sp-1, data, 0);    pop_stack();       /* num_* */   #define FOO(NUMTYPE,TYPE,NAME) \    code_number( p->PIKE_CONCAT(num_,NAME), data);   #include "program_areas.h"       /* Byte-code method    */ + #ifdef PIKE_PORTABLE_BYTECODE +  code_number(PIKE_BYTECODE_PORTABLE, data); + #else /* !PIKE_PORTABLE_BYTECODE */    code_number(PIKE_BYTECODE_METHOD, data); -  +    #ifdef PIKE_USE_MACHINE_CODE    /* Add the checksum of the instrs array. */    code_number(instrs_checksum, data);   #endif /* PIKE_USE_MACHINE_CODE */       /* program */   #ifdef ENCODE_PROGRAM   #ifdef PIKE_DEBUG    {    ptrdiff_t bufpos = data->buf.s.len;
pike.git/src/encode.c:1225:   #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);    + #endif /* PIKE_PORTABLE_BYTECODE */ +     {    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, 0);    }    }       EDB(5, dump_program_tables(p, data->depth));    -  + #ifdef PIKE_PORTABLE_BYTECODE +  /* Encode the efun constants since they are needed by the optimizer. */ +  { +  struct svalue str_sval; +  str_sval.type = T_STRING; +  str_sval.subtype = 0; +  +  /* constants */ +  for(d=0;d<p->num_constants;d++) +  { +  if ((p->constants[d].sval.type != T_FUNCTION) || +  (p->constants[d].sval.subtype != FUNCTION_BUILTIN)) { +  continue; +  } +  code_number(ID_ENTRY_EFUN_CONSTANT, data); +  code_number(d, data); +  /* value */ +  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, 0); +  } else { +  push_int(0); +  encode_value2(Pike_sp-1, data, 0); +  dmalloc_touch_svalue(Pike_sp-1); +  Pike_sp--; +  } +  } +  } + #endif /* PIKE_PORTABLE_BYTECODE */    /* 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,
pike.git/src/encode.c:1379:       /* type */    ref_push_type_value(id->type);    encode_value2(Pike_sp-1, data, 0);    pop_stack();       /* func_flags (aka identifier_flags) */    code_number(id->identifier_flags, data);       /* func */ + #ifdef PIKE_PORTABLE_BYTECODE +  if (id->func.offset >= 0) { +  /* Code the number of the string containing +  * the raw bytecode. +  */ +  code_number(((INT32 *)(p->program+id->func.offset))[-1], +  data); +  } else { +  /* Prototype */ +  code_number(-1, data); +  } + #else /* !PIKE_PORTABLE_BYTECODE */    code_number(id->func.offset, data); -  + #endif /* PIKE_PORTABLE_BYTECODE */       /* opt_flags */    code_number(id->opt_flags, data);    break;       case IDENTIFIER_C_FUNCTION:    /* Not supported. */    Pike_error("Cannot encode functions implemented in C "    "(identifier='%s').\n",    p->identifiers[d].name->str);
pike.git/src/encode.c:1517:       /* 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++)    { + #ifdef PIKE_PORTABLE_BYTECODE +  if ((p->constants[d].sval.type == T_FUNCTION) && +  (p->constants[d].sval.subtype == FUNCTION_BUILTIN)) { +  /* Already encoded above. */ +  continue; +  } + #endif /* PIKE_PORTABLE_BYTECODE */    /* value */    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, 0);    } else {    push_int(0);    encode_value2(Pike_sp-1, data, 0);
pike.git/src/encode.c:2177:    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();   }    + /* Decode bytecode string @[string_no]. +  * Returns resulting offset in p->program. +  */ + static INT32 decode_portable_bytecode(INT32 string_no) + { +  struct program *p = Pike_compiler->new_program; +  struct pike_string *bytecode; +  struct pike_string *current_file=NULL; +  INT32 current_line=0; +  int e; +  ONERROR err; +  +  if ((string_no < 0) || (string_no >= p->num_strings)) { +  Pike_error("Bad bytecode string number: %d (expected 0 - %d).\n", +  string_no, p->num_strings-1); +  } +  +  bytecode = p->strings[string_no]; +  +  if (bytecode->len % 3) { +  Pike_error("Bad bytecode string length: %d (expected multiple of 3).\n", +  bytecode->len); +  } +  +  init_bytecode(); +  +  SET_ONERROR(err, exit_bytecode, NULL); +  +  switch(bytecode->size_shift) { + #define EMIT_BYTECODE(STR) do { \ +  for (e = 0; e < bytecode->len; e += 3) { \ +  if (STR(bytecode)[e] == F_FILENAME) { \ +  INT32 strno = STR(bytecode)[e+1]; \ +  if ((strno < 0) || (strno >= p->num_strings)) { \ +  Pike_error("Bad filename directive number:" \ +  " %d (expected 0 - %d).\n", \ +  strno, p->num_strings); \ +  } \ +  current_file = p->strings[strno]; \ +  } else if (STR(bytecode)[e] == F_LINE) { \ +  current_line = STR(bytecode)[e+1]; \ +  } else { \ +  insert_opcode2(STR(bytecode)[e], \ +  STR(bytecode)[e+1], \ +  STR(bytecode)[e+2], \ +  current_line, \ +  current_file); \ +  } \ +  } \ +  } while(0) +  case 2: +  EMIT_BYTECODE(STR2); +  break; +  case 1: +  EMIT_BYTECODE(STR1); +  break; +  case 0: +  EMIT_BYTECODE(STR0); +  break; + #undef EMIT_BYTECODE +  default: +  Pike_fatal("Bad size_shift: %d\n", bytecode->size_shift); +  } +  UNSET_ONERROR(err); +  return assemble(1); + } +    static void decode_value2(struct decode_data *data)      #ifdef PIKE_DEBUG   #undef decode_value2   #define decode_value2(X) do { struct svalue *_=Pike_sp; decode_value2_(X); if(Pike_sp!=_+1) Pike_fatal("decode_value2 failed!\n"); } while(0)   #endif         {    INT32 what, e, num, numh;
pike.git/src/encode.c:3365:    dmalloc_touch_svalue(Pike_sp-1);    Pike_sp--;       /* Decode lengths. */   #define FOO(NUMTYPE,TYPE,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) { +  if (bytecode_method == PIKE_BYTECODE_PORTABLE) { +  } else if (bytecode_method != PIKE_BYTECODE_METHOD) {    Pike_error("Unsupported byte-code method: %d\n", bytecode_method); -  } +  } else {      #ifdef PIKE_USE_MACHINE_CODE    {    size_t csum;    /* Check the checksum of the instrs array. */    decode_number(csum, data);    if (csum != instrs_checksum) {    Pike_error("Bad instruction checksum: %d (expected %d)\n",    csum, instrs_checksum);    }
pike.git/src/encode.c:3416:    /* 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);    }    +  /* 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().    */       /* Decode strings */    for (e=0; e<local_num_strings; e++) {    decode_value2(data);    if (Pike_sp[-1].type != T_STRING) {    ref_push_program (p);    decode_error(Pike_sp - 1, Pike_sp - 2,
pike.git/src/encode.c:3613:    ref_push_program (p);    decode_error(Pike_sp - 1, Pike_sp - 2,    "Bad function type (not a type): ");    }       /* func_flags (aka identifier_flags) */    decode_number(func_flags, data);       /* func */    decode_number(func.offset, data); +  if (bytecode_method == PIKE_BYTECODE_PORTABLE && +  func.offset != -1) { +  EDB(2, +  fprintf(stderr, "%*sDecoding portable bytecode.\n", +  data->depth, "")); +  func.offset = decode_portable_bytecode(func.offset); +  }       /* opt_flags */    decode_number(opt_flags, data);       /* FIXME:    * Verify validity of func_flags, func.offset & opt_flags    */       /* Expected identifier offset */    decode_number(no, data);