WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

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