diff options
Diffstat (limited to 'src/stateless/cp/trex_stream_vm.cpp')
-rw-r--r-- | src/stateless/cp/trex_stream_vm.cpp | 90 |
1 files changed, 84 insertions, 6 deletions
diff --git a/src/stateless/cp/trex_stream_vm.cpp b/src/stateless/cp/trex_stream_vm.cpp index 2984b896..a3f585ad 100644 --- a/src/stateless/cp/trex_stream_vm.cpp +++ b/src/stateless/cp/trex_stream_vm.cpp @@ -449,7 +449,7 @@ void StreamVm::build_program(){ op = StreamDPVmInstructions::ditRANDOM64 ; } - StreamDPOpFlowVar32 fv64; + StreamDPOpFlowVar64 fv64; fv64.m_op = op; fv64.m_flow_offset = get_var_offset(lpMan->m_var_name); fv64.m_min_val = (uint64_t)lpMan->m_min_value; @@ -577,19 +577,19 @@ void StreamVm::build_bss() { switch (ins_man->m_size_bytes) { case 1: - *p=(uint8_t)ins_man->m_init_value; + *p=(uint8_t)ins_man->get_bss_init_value(); p+=1; break; case 2: - *((uint16_t*)p)=(uint16_t)ins_man->m_init_value; + *((uint16_t*)p)=(uint16_t)ins_man->get_bss_init_value(); p+=2; break; case 4: - *((uint32_t*)p)=(uint32_t)ins_man->m_init_value; + *((uint32_t*)p)=(uint32_t)ins_man->get_bss_init_value(); p+=4; break; case 8: - *((uint64_t*)p)=(uint64_t)ins_man->m_init_value; + *((uint64_t*)p)=(uint64_t)ins_man->get_bss_init_value(); p+=8; break; default: @@ -621,9 +621,58 @@ void StreamVm::build_bss() { } } +/** + * set the VM split instruction + * instr is a pointer to an instruction inside + * the VM program + * + */ +void +StreamVm::set_split_instruction(StreamVmInstructionVar *instr) { + m_split_instr = instr; +} + +/** + * copy instructions from this VM to 'other' + * + * @author imarom (22-Dec-15) + * + * @param other + */ +void +StreamVm::copy_instructions(StreamVm &other) const { + /* clear previous if any exists */ + for (auto instr : other.m_inst_list) { + delete instr; + } + + other.m_inst_list.clear(); + for (auto instr : m_inst_list) { + StreamVmInstruction *new_instr = instr->clone(); + other.m_inst_list.push_back(new_instr); -void StreamVm::compile() { + /* for the split instruction - find the right one */ + if (instr == m_split_instr) { + /* dynamic cast must succeed here */ + other.m_split_instr = dynamic_cast<StreamVmInstructionVar *>(new_instr); + assert(other.m_split_instr); + } + } + +} + +/** + * actual work - compile the VM + * + */ +void StreamVm::compile(uint16_t pkt_len) { + + if (is_vm_empty()) { + return; + } + + m_pkt_size = pkt_len; /* build flow var offset table */ build_flow_var_table() ; @@ -638,6 +687,11 @@ void StreamVm::compile() { ss << "maximum offset is" << get_max_packet_update_offset() << " bigger than maximum " <<svMAX_PACKET_OFFSET_CHANGE; err(ss.str()); } + + /* calculate the mbuf size that we should allocate */ + m_prefix_size = calc_writable_mbuf_size(get_max_packet_update_offset(), m_pkt_size); + + m_is_compiled = true; } @@ -648,6 +702,30 @@ StreamVm::~StreamVm() { free_bss(); } +/** +* return a pointer to a flow var / client var +* by name if exists, otherwise NULL +* +*/ +StreamVmInstructionVar * +StreamVm::lookup_var_by_name(const std::string &var_name) { + for (StreamVmInstruction *inst : m_inst_list) { + + /* try to cast up to a variable */ + StreamVmInstructionVar *var = dynamic_cast<StreamVmInstructionVar *>(inst); + if (!var) { + continue; + } + + if (var->get_var_name() == var_name) { + return var; + } + + } + + return NULL; +} + void StreamVm::Dump(FILE *fd){ fprintf(fd," instructions \n"); |