To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

Commit fde94d2b authored by qinsoon's avatar qinsoon
Browse files

implement GetElemIRef

parent b6c93384
......@@ -78,6 +78,13 @@ impl MuType {
}
}
pub fn get_elem_ty(&self) -> Option<P<MuType>> {
match self.v {
MuType_::Array(ref elem_ty, _) => Some(elem_ty.clone()),
_ => None
}
}
pub fn get_field_ty(&self, index: usize) -> Option<P<MuType>> {
match self.v {
MuType_::Struct(ref tag) => {
......
......@@ -2944,6 +2944,99 @@ impl <'a> InstructionSelection {
mem
}
}
Instruction_::GetElementIRef {base, index, ..} => {
let ref base = ops[base];
let ref index = ops[index];
let ref iref_array_ty = base.clone_value().ty;
let array_ty = match iref_array_ty.get_referenced_ty() {
Some(ty) => ty,
None => panic!("expected base in GetElemIRef to be type IRef, found {}", iref_array_ty)
};
let ele_ty = match array_ty.get_elem_ty() {
Some(ty) => ty,
None => panic!("expected base in GetElemIRef to be type Array, found {}", array_ty)
};
let ele_ty_size = vm.get_backend_type_info(ele_ty.id()).size;
if self.match_iimm(index) {
let index = self.node_iimm_to_i32(index);
let offset = ele_ty_size as i32 * index;
match base.v {
// GETELEMIREF(GETIREF) -> add offset
TreeNode_::Instruction(Instruction{v: Instruction_::GetIRef(_), ..}) => {
let mem = self.emit_get_mem_from_inst_inner(base, f_content, f_context, vm);
let ret = self.addr_const_offset_adjust(mem, offset as u64, vm);
trace!("MEM from GETELEMIREF(GETIREF, const): {}", ret);
ret
},
// GETELEMIREF(GETFIELDIREF) -> add offset
TreeNode_::Instruction(Instruction{v: Instruction_::GetFieldIRef{..}, ..}) => {
let mem = self.emit_get_mem_from_inst_inner(base, f_content, f_context, vm);
let ret = self.addr_const_offset_adjust(mem, offset as u64, vm);
trace!("MEM from GETELEMIREF(GETFIELDIREF, const): {}", ret);
ret
},
// GETELEMIREF(ireg) => [base + offset]
_ => {
let tmp = self.emit_ireg(base, f_content, f_context, vm);
let ret = MemoryLocation::Address {
base: tmp,
offset: Some(self.make_value_int_const(offset as u64, vm)),
index: None,
scale: None
};
trace!("MEM from GETELEMIREF(ireg, const): {}", ret);
ret
}
}
} else {
let tmp_index = self.emit_ireg(index, f_content, f_context, vm);
let scale : u8 = match ele_ty_size {
8 | 4 | 2 | 1 => ele_ty_size as u8,
_ => unimplemented!()
};
match base.v {
// GETELEMIREF(IREF, ireg) -> add index and scale
TreeNode_::Instruction(Instruction{v: Instruction_::GetIRef(_), ..}) => {
let mem = self.emit_get_mem_from_inst_inner(base, f_content, f_context, vm);
let ret = self.addr_append_index_scale(mem, tmp_index, scale, vm);
trace!("MEM from GETELEMIREF(GETIREF, ireg): {}", ret);
ret
}
// GETELEMIREF(GETFIELDIREF, ireg) -> add index and scale
TreeNode_::Instruction(Instruction{v: Instruction_::GetFieldIRef{..}, ..}) => {
let mem = self.emit_get_mem_from_inst_inner(base, f_content, f_context, vm);
let ret = self.addr_append_index_scale(mem, tmp_index, scale, vm);
trace!("MEM from GETELEMIREF(GETFIELDIREF, ireg): {}", ret);
ret
}
// GETELEMIREF(ireg, ireg)
_ => {
let tmp = self.emit_ireg(base, f_content, f_context, vm);
let ret = MemoryLocation::Address {
base: tmp,
offset: None,
index: Some(tmp_index),
scale: Some(scale)
};
trace!("MEM from GETELEMIREF(ireg, ireg): {}", ret);
ret
}
}
}
}
_ => unimplemented!()
}
},
......
......@@ -224,7 +224,7 @@ impl MuCtx {
}
pub fn get_elem_iref(&mut self, opnd: &APIHandle, index: &APIHandle) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.handle_get_elem_iref(opnd, index))
}
pub fn shift_iref(&mut self, opnd: &APIHandle, offset: &APIHandle) -> *const APIHandle {
......
......@@ -996,6 +996,25 @@ impl <'a> VM {
})
}
pub fn handle_get_elem_iref(&self, handle_iref: APIHandleArg, index: APIHandleArg) -> APIHandleResult {
let (ty, addr) = handle_iref.v.as_iref();
let index = self.handle_to_uint64(index);
let ele_ty = match ty.get_elem_ty() {
Some(ty) => ty,
None => panic!("cannot get element ty from {}", ty)
};
let elem_addr = {
let backend_ty = self.get_backend_type_info(ele_ty.id());
addr.plus(backend_ty.size * (index as usize))
};
self.new_handle(APIHandle {
id: self.next_id(),
v : APIHandleValue::IRef(ele_ty, elem_addr)
})
}
pub fn handle_get_var_part_iref(&self, handle_iref: APIHandleArg) -> APIHandleResult {
let (ty, addr) = handle_iref.v.as_iref();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment