MCPcopy Create free account
hub / github.com/WebAssembly/wabt / LoadStore

Method LoadStore

src/decompiler.cc:260–352  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

258 }
259
260 void LoadStore(Value& val,
261 const Node& addr_exp,
262 uint64_t offset,
263 Opcode opc,
264 Address align,
265 Type op_type) {
266 bool append_type = true;
267 auto access = lst.GenAccess(offset, addr_exp);
268 if (!access.empty()) {
269 if (access == "*") {
270 // The variable was declared as a typed pointer, so this access
271 // doesn't need a type.
272 append_type = false;
273 } else {
274 // We can do this load/store as a struct access.
275 BracketIfNeeded(val, Precedence::Indexing);
276 val.v.back() += "." + access;
277 return;
278 }
279 }
280 // Detect absolute addressing, which we try to turn into references to the
281 // data section when possible.
282 uint64_t abs_base;
283 if (ConstIntVal(addr_exp.e, abs_base)) {
284 // We don't care what part of the absolute address was stored where,
285 // 1[0] and 0[1] are the same.
286 abs_base += offset;
287 // FIXME: make this less expensive with a binary search or whatever.
288 for (auto dat : mc.module.data_segments) {
289 uint64_t dat_base;
290 if (dat->offset.size() == 1 &&
291 ConstIntVal(&dat->offset.front(), dat_base) &&
292 abs_base >= dat_base && abs_base < dat_base + dat->data.size()) {
293 // We are inside the range of this data segment!
294 // Turn expression into data_name[index]
295 val = Value{{dat->name}, Precedence::Atomic};
296 // The new offset is from the start of the data segment, instead of
297 // whatever it was.. this may be a different value from both the
298 // original const and offset!
299 offset = abs_base - dat_base;
300 }
301 }
302 }
303 // Do the load/store as a generalized indexing operation.
304 // The offset is divisible by the alignment in 99.99% of
305 // cases, but the spec doesn't guarantee it, so we must
306 // have a backup syntax.
307 auto index = offset % align == 0
308 ? std::to_string(offset / align)
309 : cat(std::to_string(offset), "@", std::to_string(align));
310 // Detect the very common case of (base + (index << 2))[0]:int etc.
311 // so we can instead do base[index]:int
312 // TODO: (index << 2) on the left of + occurs also.
313 // TODO: sadly this does not address cases where the shift amount > align.
314 // (which happens for arrays of structs or arrays of long (with align=4)).
315 // TODO: also very common is (v = base + (index << 2))[0]:int
316 if (addr_exp.etype == ExprType::Binary) {
317 auto& pe = *cast<BinaryExpr>(addr_exp.e);

Callers

nothing calls this directly

Calls 11

catFunction · 0.85
GetDecompTypeNameFunction · 0.85
GetMemoryTypeFunction · 0.85
GenAccessMethod · 0.80
backMethod · 0.80
frontMethod · 0.80
GenAlignMethod · 0.80
emptyMethod · 0.45
sizeMethod · 0.45
typeMethod · 0.45
u32Method · 0.45

Tested by

no test coverage detected