Branch: Tag:

2004-05-11

2004-05-11 15:42:50 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Backported support for the PIKE_PORTABLE_BYTECODE method from Pike 7.6.

Rev: src/encode.c:1.182

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.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"
32:   #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 */   
1195:       /* 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);
1232:    /* linenumbers */    adddata2(p->linenumbers, p->num_linenumbers);    + #endif /* PIKE_PORTABLE_BYTECODE */ +     {    struct svalue str_sval;    str_sval.type = T_STRING;
1245:       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;
1386:    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);
1524:    /* 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);   
2184:    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
3372:       /* 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    {
3423:    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().    */
3620:       /* 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);