Пример #1
0
/**
 * Dump byte-code and idx-to-literal map to snapshot
 *
 * @return true, upon success (i.e. buffer size is enough),
 *         false - otherwise.
 */
bool
serializer_dump_bytecode_with_idx_map (uint8_t *buffer_p, /**< buffer to dump to */
                                       size_t buffer_size, /**< buffer size */
                                       size_t *in_out_buffer_offset_p, /**< in-out: buffer write offset */
                                       const bytecode_data_header_t *bytecode_data_p, /**< byte-code data */
                                       const lit_mem_to_snapshot_id_map_entry_t *lit_map_p, /**< map from literal
                                                                                             *   identifiers in
                                                                                             *   literal storage
                                                                                             *   to literal offsets
                                                                                             *   in snapshot */
                                       uint32_t literals_num, /**< literals number */
                                       uint32_t *out_bytecode_size_p, /**< out: size of dumped instructions array */
                                       uint32_t *out_idx_to_lit_map_size_p) /**< out: side of dumped
                                                                             *        idx to literals map */
{
  JERRY_ASSERT (bytecode_data_p->next_header_cp == MEM_CP_NULL);

  vm_instr_counter_t instrs_num = bytecode_data_p->instrs_count;

  const size_t instrs_array_size = sizeof (vm_instr_t) * instrs_num;
  if (*in_out_buffer_offset_p + instrs_array_size > buffer_size)
  {
    return false;
  }
  memcpy (buffer_p + *in_out_buffer_offset_p, bytecode_data_p->instrs_p, instrs_array_size);
  *in_out_buffer_offset_p += instrs_array_size;

  *out_bytecode_size_p = (uint32_t) (sizeof (vm_instr_t) * instrs_num);

  lit_id_hash_table *lit_id_hash_p = MEM_CP_GET_POINTER (lit_id_hash_table, bytecode_data_p->lit_id_hash_cp);
  uint32_t idx_to_lit_map_size = lit_id_hash_table_dump_for_snapshot (buffer_p,
                                                                      buffer_size,
                                                                      in_out_buffer_offset_p,
                                                                      lit_id_hash_p,
                                                                      lit_map_p,
                                                                      literals_num,
                                                                      instrs_num);

  if (idx_to_lit_map_size == 0)
  {
    return false;
  }
  else
  {
    *out_idx_to_lit_map_size_p = idx_to_lit_map_size;

    return true;
  }
} /* serializer_dump_bytecode_with_idx_map */
Пример #2
0
/**
 * Dump byte-code and idx-to-literal map of a single scope to snapshot
 *
 * @return true, upon success (i.e. buffer size is enough),
 *         false - otherwise.
 */
static bool
bc_save_bytecode_with_idx_map (uint8_t *buffer_p, /**< buffer to dump to */
                               size_t buffer_size, /**< buffer size */
                               size_t *in_out_buffer_offset_p, /**< in-out: buffer write offset */
                               const bytecode_data_header_t *bytecode_data_p, /**< byte-code data */
                               const lit_mem_to_snapshot_id_map_entry_t *lit_map_p, /**< map from literal
                                                                                     *   identifiers in
                                                                                     *   literal storage
                                                                                     *   to literal offsets
                                                                                     *   in snapshot */
                               uint32_t literals_num) /**< literals number */
{
  JERRY_ASSERT (JERRY_ALIGNUP (*in_out_buffer_offset_p, MEM_ALIGNMENT) == *in_out_buffer_offset_p);

  jerry_snapshot_bytecode_header_t bytecode_header;
  bytecode_header.func_scopes_count = bytecode_data_p->func_scopes_count;
  bytecode_header.var_decls_count = bytecode_data_p->var_decls_count;
  bytecode_header.is_strict = bytecode_data_p->is_strict;
  bytecode_header.is_ref_arguments_identifier = bytecode_data_p->is_ref_arguments_identifier;
  bytecode_header.is_ref_eval_identifier = bytecode_data_p->is_ref_eval_identifier;
  bytecode_header.is_args_moved_to_regs = bytecode_data_p->is_args_moved_to_regs;
  bytecode_header.is_no_lex_env = bytecode_data_p->is_no_lex_env;
  size_t bytecode_header_offset = *in_out_buffer_offset_p;

  /* Dump instructions */
  *in_out_buffer_offset_p += JERRY_ALIGNUP (sizeof (jerry_snapshot_bytecode_header_t), MEM_ALIGNMENT);

  vm_instr_counter_t instrs_num = bytecode_data_p->instrs_count;

  const size_t instrs_array_size = sizeof (vm_instr_t) * instrs_num;
  if (*in_out_buffer_offset_p + instrs_array_size > buffer_size)
  {
    return false;
  }
  memcpy (buffer_p + *in_out_buffer_offset_p, bytecode_data_p->instrs_p, instrs_array_size);
  *in_out_buffer_offset_p += instrs_array_size;

  bytecode_header.instrs_size = (uint32_t) (sizeof (vm_instr_t) * instrs_num);

  /* Dump variable declarations */
  mem_cpointer_t *func_scopes_p = MEM_CP_GET_POINTER (mem_cpointer_t, bytecode_data_p->declarations_cp);
  lit_cpointer_t *var_decls_p = (lit_cpointer_t *) (func_scopes_p + bytecode_data_p->func_scopes_count);
  uint32_t null_var_decls_num = 0;
  for (uint32_t i = 0; i < bytecode_header.var_decls_count; ++i)
  {
    lit_cpointer_t lit_cp = var_decls_p[i];

    if (lit_cp.packed_value == MEM_CP_NULL)
    {
      null_var_decls_num++;
      continue;
    }

    uint32_t offset = bc_find_lit_offset (lit_cp, lit_map_p, literals_num);
    if (!jrt_write_to_buffer_by_offset (buffer_p, buffer_size, in_out_buffer_offset_p, &offset, sizeof (offset)))
    {
      return false;
    }
  }
  bytecode_header.var_decls_count -= null_var_decls_num;

  /* Dump uid->lit_cp hash table */
  lit_id_hash_table *lit_id_hash_p = MEM_CP_GET_POINTER (lit_id_hash_table, bytecode_data_p->lit_id_hash_cp);
  uint32_t idx_to_lit_map_size = lit_id_hash_table_dump_for_snapshot (buffer_p,
                                                                      buffer_size,
                                                                      in_out_buffer_offset_p,
                                                                      lit_id_hash_p,
                                                                      lit_map_p,
                                                                      literals_num,
                                                                      instrs_num);

  if (idx_to_lit_map_size == 0)
  {
    return false;
  }

  bytecode_header.idx_to_lit_map_size = idx_to_lit_map_size;

  /* Align to write next bytecode data at aligned address */
  bytecode_header.size = (uint32_t) (*in_out_buffer_offset_p - bytecode_header_offset);
  JERRY_ASSERT (bytecode_header.size == JERRY_ALIGNUP (sizeof (jerry_snapshot_bytecode_header_t), MEM_ALIGNMENT)
                                        + bytecode_header.instrs_size
                                        + bytecode_header.var_decls_count * sizeof (uint32_t)
                                        + idx_to_lit_map_size);

  if (!bc_align_data_in_output_buffer (&bytecode_header.size,
                                       buffer_p,
                                       buffer_size,
                                       in_out_buffer_offset_p))
  {
    return false;
  }

  /* Dump header at the saved offset */
  if (!jrt_write_to_buffer_by_offset (buffer_p,
                                      buffer_size,
                                      &bytecode_header_offset,
                                      &bytecode_header,
                                      sizeof (bytecode_header)))
  {
    return false;
  }

  return true;
} /* bc_save_bytecode_with_idx_map */