/* Postparser. Init literal indexes 'hash' table. Reorder function declarations. Rewrite instructions' temporary uids with their keys in literal indexes 'hash' table. */ vm_instr_t * scopes_tree_raw_data (scopes_tree tree, /**< scopes tree to convert to byte-code array */ uint8_t *buffer_p, /**< buffer for byte-code array and literal identifiers hash table */ size_t instructions_array_size, /**< size of space for byte-code array */ lit_id_hash_table *lit_ids) /**< literal identifiers hash table */ { JERRY_ASSERT (lit_ids); assert_tree (tree); if (lit_id_to_uid != null_hash) { hash_table_free (lit_id_to_uid); lit_id_to_uid = null_hash; } next_uid = 0; global_oc = 0; /* Dump bytecode and fill literal indexes 'hash' table. */ JERRY_ASSERT (instructions_array_size >= sizeof (insts_data_header_t) + (size_t) (scopes_tree_count_instructions (tree)) * sizeof (vm_instr_t)); insts_data_header_t *opcodes_data = (insts_data_header_t *) buffer_p; memset (opcodes_data, 0, instructions_array_size); vm_instr_t *instrs = (vm_instr_t *)(((uint8_t*) opcodes_data) + sizeof (insts_data_header_t)); merge_subscopes (tree, instrs, lit_ids); if (lit_id_to_uid != null_hash) { hash_table_free (lit_id_to_uid); lit_id_to_uid = null_hash; } MEM_CP_SET_POINTER (opcodes_data->lit_id_hash_cp, lit_ids); return instrs; } /* scopes_tree_raw_data */
vm_instr_counter_t scopes_tree_count_instructions (scopes_tree t) { assert_tree (t); vm_instr_counter_t res = (vm_instr_counter_t) (t->instrs_count + t->var_decls_cout); for (uint8_t i = 0; i < t->t.children_num; i++) { res = (vm_instr_counter_t) ( res + scopes_tree_count_instructions ( *(scopes_tree *) linked_list_element (t->t.children, i))); } return res; }
const vm_instr_t * serializer_merge_scopes_into_bytecode (void) { bytecode_data.instrs_count = scopes_tree_count_instructions (current_scope); const size_t buckets_count = scopes_tree_count_literals_in_blocks (current_scope); const size_t blocks_count = (size_t) bytecode_data.instrs_count / BLOCK_SIZE + 1; const vm_instr_counter_t instrs_count = scopes_tree_count_instructions (current_scope); const size_t bytecode_array_size = JERRY_ALIGNUP (sizeof (insts_data_header_t) + instrs_count * sizeof (vm_instr_t), MEM_ALIGNMENT); const size_t lit_id_hash_table_size = JERRY_ALIGNUP (lit_id_hash_table_get_size_for_table (buckets_count, blocks_count), MEM_ALIGNMENT); uint8_t *buffer_p = (uint8_t*) mem_heap_alloc_block (bytecode_array_size + lit_id_hash_table_size, MEM_HEAP_ALLOC_LONG_TERM); lit_id_hash_table *lit_id_hash = lit_id_hash_table_init (buffer_p + bytecode_array_size, lit_id_hash_table_size, buckets_count, blocks_count); const vm_instr_t *instrs_p = scopes_tree_raw_data (current_scope, buffer_p, bytecode_array_size, lit_id_hash); insts_data_header_t *header_p = (insts_data_header_t*) buffer_p; MEM_CP_SET_POINTER (header_p->next_instrs_cp, bytecode_data.instrs_p); header_p->instructions_number = instrs_count; bytecode_data.instrs_p = instrs_p; if (print_instrs) { lit_dump_literals (); serializer_print_instrs (instrs_p, bytecode_data.instrs_count); } return instrs_p; }
/** * Merge scopes tree into bytecode * * @return pointer to generated bytecode */ const bytecode_data_header_t * serializer_merge_scopes_into_bytecode (void) { const size_t buckets_count = scopes_tree_count_literals_in_blocks (current_scope); const vm_instr_counter_t instrs_count = scopes_tree_count_instructions (current_scope); const size_t blocks_count = JERRY_ALIGNUP (instrs_count, BLOCK_SIZE) / BLOCK_SIZE; const size_t bytecode_size = JERRY_ALIGNUP (instrs_count * sizeof (vm_instr_t), MEM_ALIGNMENT); const size_t hash_table_size = lit_id_hash_table_get_size_for_table (buckets_count, blocks_count); const size_t header_and_hash_table_size = JERRY_ALIGNUP (sizeof (bytecode_data_header_t) + hash_table_size, MEM_ALIGNMENT); uint8_t *buffer_p = (uint8_t*) mem_heap_alloc_block (bytecode_size + header_and_hash_table_size, MEM_HEAP_ALLOC_LONG_TERM); lit_id_hash_table *lit_id_hash = lit_id_hash_table_init (buffer_p + sizeof (bytecode_data_header_t), hash_table_size, buckets_count, blocks_count); vm_instr_t *bytecode_p = scopes_tree_raw_data (current_scope, buffer_p + header_and_hash_table_size, bytecode_size, lit_id_hash); bytecode_data_header_t *header_p = (bytecode_data_header_t *) buffer_p; MEM_CP_SET_POINTER (header_p->lit_id_hash_cp, lit_id_hash); header_p->instrs_p = bytecode_p; header_p->instrs_count = instrs_count; MEM_CP_SET_POINTER (header_p->next_header_cp, first_bytecode_header_p); first_bytecode_header_p = header_p; if (print_instrs) { lit_dump_literals (); serializer_print_instrs (header_p); } return header_p; } /* serializer_merge_scopes_into_bytecode */
vm_instr_counter_t serializer_count_instrs_in_subscopes (void) { return (vm_instr_counter_t) (scopes_tree_count_instructions (current_scope) - scopes_tree_instrs_num (current_scope)); }