def _lea(i, src, dst, stack, **kwargs): if issubclass(src.var_type, FileDescriptorDatastructure): if not isinstance(src, _mem.ConstVar): raise TranslationError( i.starts_line, 'Cannot handle non-const file descriptor datastructures') return _mov(bi.MapFdImm(src.val.fd), dst) setup = [] if isinstance(src, _mem.ConstVar): # We have to lay it down in memory ourselves, sadly tmp_src = stack.alloc(src.var_type) tmp_reg = _get_var_reg(tmp_src) setup = _mov_const(src.var_type, src.val, tmp_reg, tmp_src.offset) src = tmp_src # TODO: fix types. Right now, dt may by a ulong for addrof, because we # can't plug in real return types yet. # if not isinstance(dst, bi.Reg): # st, dt = src.var_type, dst.var_type # assert issubclass(dt,_types.Ptr) and dt.var_type == st reg = _get_var_reg(src) if src.offset == 0: return setup + _mov(reg, dst) else: return ( setup + [bi.Mov(reg, bi.Reg.R0), bi.Add(bi.Imm(src.offset), bi.Reg.R0)] + _mov(bi.Reg.R0, dst))
def _store_subscr_map(i, **kwargs): v, m, k = i.src_vars if not isinstance(m, _mem.ConstVar): raise TranslationError(i.starts_line, 'Cannot subscript dynamically selected map') return ([bi.Mov(bi.MapFdImm(m.val.fd), bi.Reg.R1)] + _lea(i, k, bi.Reg.R2, **kwargs) + _lea(i, v, bi.Reg.R3, **kwargs) + [ bi.Mov(bi.Imm(0), bi.Reg.R4), bi.Call(bi.Imm(funcs.map_update_elem.num)) ])
def _delete_subscr(i, **kwargs): if issubclass(i.src_vars[1].var_type, ctypes.Array): raise TranslationError(i.starts_line, 'Cannot delete from array') m, k = i.src_vars if not isinstance(m, _mem.ConstVar): raise TranslationError(i.starts_line, 'Cannot delete from dynamically selected map') return ([bi.Mov(bi.MapFdImm(m.val.fd), bi.Reg.R1)] + _lea(i, k, bi.Reg.R2, **kwargs) + [bi.Call(bi.Imm(funcs.map_delete_elem.num))])
def _binary_subscr_map(i, **kwargs): m, k, dv = i.src_vars[0], i.src_vars[1], i.dst_vars[0] if not isinstance(m, _mem.ConstVar): raise TranslationError(i.starts_line, 'Cannot subscript dynamically select map') found, done = _make_tmp_label(), _make_tmp_label() ret = [] ret.extend(_mov(bi.MapFdImm(m.val.fd), bi.Reg.R1)) ret.extend(_lea(i, k, bi.Reg.R2, **kwargs)) ret.extend([ bi.Call(bi.Imm(funcs.map_lookup_elem.num)), ]) if _is_ptr(dv.var_type): sz = _get_cdata_size(dv.var_type) ret.extend(_mov(bi.Reg.R0, dv)) else: ret.extend([ bi.JumpIfNotEqual(bi.Imm(0), bi.Reg.R0, found), ]) # Move default value dr = _get_var_reg(dv) ret.extend(_mov_const(dv.var_type, m.val.DEFAULT_VALUE, dr, dv.offset)) ret.extend([ bi.Jump(done), bi.Label(found), ]) # Primitives by value, others by reference if issubclass(dv.var_type, _ctypes._SimpleCData): sz = _get_cdata_size(dv.var_type) ret.extend(_mov(bi.Mem(bi.Reg.R0, 0, sz), dv)) else: ret.extend(_mov(bi.Reg.R0, dv)) ret.append(bi.Label(done)) return ret
def _mov_const(val_type, val, reg, offset): if issubclass(val_type, FileDescriptorDatastructure): return (_mov(bi.MapFdImm(val.fd), bi.Reg.R0) + _mov(bi.Reg.R0, bi.Mem(reg, offset, bi.Size.Quad))) if issubclass(val_type, _ctypes._SimpleCData): # They may have passed us a vanilla int here if hasattr(val, 'value'): val = val.value dst_mem = bi.Mem(reg, offset, _get_cdata_size(val_type)) return [bi.Mov(bi.Imm(val), dst_mem)] ret = [] if issubclass(val_type, ctypes.Array): for i in range(val_type._length_): el_off = offset + ctypes.sizeof(val_type._type_) * i el = val[i] if i < len(val) else val_type._type_() ret.extend(_mov_const(val_type._type_, el, reg, el_off)) else: for f, t in val_type._fields_: f_val = getattr(val, f) f_off = getattr(val_type, f).offset ret.extend(_mov_const(t, f_val, reg, offset + f_off)) return ret