/** * 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 */
/** * 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 */