diff options
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 5635282f7..818af49ba 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -1138,20 +1138,19 @@ Expression* SExpressionWasmBuilder::makeConst(Element& s, Type type) { return ret; } -static uint8_t parseMemBytes(const char** in, uint8_t fallback) { +static uint8_t parseMemBytes(const char*& s, uint8_t fallback) { uint8_t ret; - const char* s = *in; if (s[0] == '8') { ret = 1; - (*in)++; + s++; } else if (s[0] == '1') { if (s[1] != '6') throw ParseException("expected 16 for memop size"); ret = 2; - *in += 2; + s += 2; } else if (s[0] == '3') { if (s[1] != '2') throw ParseException("expected 32 for memop size");; ret = 4; - *in += 2; + s += 2; } else { ret = fallback; } @@ -1185,13 +1184,23 @@ static size_t parseMemAttributes(Element& s, Address* offset, Address* align, Ad return i; } +static const char* findMemExtra(const Element& s, size_t skip, bool isAtomic) { + auto* str = s.c_str(); + auto size = strlen(str); + auto* ret = strchr(str, '.'); + if (!ret) throw ParseException("missing '.' in memory access", s.line, s.col); + ret += skip; + if (isAtomic) ret += 7; // after "type.atomic.load" + if (ret > str + size) throw ParseException("memory access ends abruptly", s.line, s.col); + return ret; +} + Expression* SExpressionWasmBuilder::makeLoad(Element& s, Type type, bool isAtomic) { - const char *extra = strchr(s[0]->c_str(), '.') + 5; // after "type.load" - if (isAtomic) extra += 7; // after "type.atomic.load" + const char* extra = findMemExtra(*s[0], 5 /* after "type.load" */, isAtomic); auto* ret = allocator.alloc<Load>(); ret->isAtomic = isAtomic; ret->type = type; - ret->bytes = parseMemBytes(&extra, getTypeSize(type)); + ret->bytes = parseMemBytes(extra, getTypeSize(type)); ret->signed_ = extra[0] && extra[1] == 's'; size_t i = parseMemAttributes(s, &ret->offset, &ret->align, ret->bytes); ret->ptr = parseExpression(s[i]); @@ -1200,12 +1209,11 @@ Expression* SExpressionWasmBuilder::makeLoad(Element& s, Type type, bool isAtomi } Expression* SExpressionWasmBuilder::makeStore(Element& s, Type type, bool isAtomic) { - const char *extra = strchr(s[0]->c_str(), '.') + 6; // after "type.store" - if (isAtomic) extra += 7; // after "type.atomic.store" + const char* extra = findMemExtra(*s[0], 6 /* after "type.store" */, isAtomic); auto ret = allocator.alloc<Store>(); ret->isAtomic = isAtomic; ret->valueType = type; - ret->bytes = parseMemBytes(&extra, getTypeSize(type)); + ret->bytes = parseMemBytes(extra, getTypeSize(type)); size_t i = parseMemAttributes(s, &ret->offset, &ret->align, ret->bytes); ret->ptr = parseExpression(s[i]); ret->value = parseExpression(s[i+1]); @@ -1214,8 +1222,8 @@ Expression* SExpressionWasmBuilder::makeStore(Element& s, Type type, bool isAtom } Expression* SExpressionWasmBuilder::makeAtomicRMWOrCmpxchg(Element& s, Type type) { - const char* extra = strchr(s[0]->c_str(), '.') + 11; // afer "type.atomic.rmw" - auto bytes = parseMemBytes(&extra, getTypeSize(type)); + const char* extra = findMemExtra(*s[0], 11 /* after "type.atomic.rmw" */, /* isAtomic = */ false); + auto bytes = parseMemBytes(extra, getTypeSize(type)); extra = strchr(extra, '.'); // after the optional '_u' and before the opcode if (!extra) throw ParseException("malformed atomic rmw instruction"); extra++; // after the '.' |